Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Implementing Array functions (indexOf, lastIndexOf, removeDuplicates...)

Explorer ,
Aug 20, 2015 Aug 20, 2015

Hi,

I'm trying to implement some functions to manipulate Arrays more easily, like I would do with other programming languages (Array.indexOf() does exist in Javascript, but seems to be missing from ExtendScript).

First, I tried to add those functions using Array.prototype; here is what I did for two of those functions:

Array.prototype.indexOf = function (value)

        {

          for (var i = 0;i<this.length;i++)

            {

                if (this == value) return i;

            }

            return -1;

        }

      

Array.prototype.removeDuplicates = function ()

        {

            var removed = [];

            for (var i = 0;i<this.length-1;i++) {

                    for (var j=i+1;j<this.length;j++) {

                        if (this == this) {              

                            removed.push(this.splice(j,)1);

                        }

                    }

                }

                return removed;

        }

It seemed to work well, but I found out that it breaks this kind of loop:

for (var i in array) {

     alert(array);

     }

The loop goes through array values, and continues beyond array.length with the functions added to the prototype.

As explained here, I found a workaround, using Object.defineProperty() instead of implementing functions in Array.proptotype

Object.defineProperty(Array.prototype, "indexOf", {

  enumerable: false,

  value: function(value) {

      for (var i = 0;i<this.length;i++)

            {

                if (this == value) return i;

            }

            return -1;

    }

});

But..... Object.defineProperty() is missing in ExtendScript too!

I don't know what to try next... Any idea?

Thanks!

TOPICS
Scripting
3.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Advocate , Aug 20, 2015 Aug 20, 2015

The primary reason that some of those functions do not exist, is because ExtendScript is based on the ECMA-262 standard. Very old Javascript, and I believe not all of it is implemented.

Pg. 3 of the CS6 scripting guide (only full written guide Adobe has at the moment) After Effects Developer Center | Adobe Developer Connection:

The ExtendScript language

"After Effects scripts use the Adobe ExtendScript language, which is an extended form of JavaScript used by several Adobe applications, including

...
Translate
Advocate ,
Aug 20, 2015 Aug 20, 2015

The primary reason that some of those functions do not exist, is because ExtendScript is based on the ECMA-262 standard. Very old Javascript, and I believe not all of it is implemented.

Pg. 3 of the CS6 scripting guide (only full written guide Adobe has at the moment) After Effects Developer Center | Adobe Developer Connection:

The ExtendScript language

"After Effects scripts use the Adobe ExtendScript language, which is an extended form of JavaScript used by several Adobe applications, including Photoshop, Illustrator, and InDesign. ExtendScript implements the JavaScript language according to the ECMA-262 specification. The After Effects scripting engine supports the 3rd Edition of the ECMA-262 Standard, including its notational and lexical conventions, types, objects, expressions, and statements. ExtendScript also implements the E4X ECMA-357 specification, which defines access to data in XML format."


While I know a lot of developers have done prototyping, I've found it to be troublesome personally, especially if your code travels outside of your machine. I've just simply made standalone functions for all of my scripts. It has been easier to reuse code and create some (not all) of the missing functions that would be nice to have from current day Javascript.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 21, 2015 Aug 21, 2015

Thanks!

I should have started by reading the guide...

I finally used standalone methods as you described, but I believe prototyping well made would have made things easier for further dev.

I usually get confused about what methods are implemented or not, in what language, and I'm used to implement what I miss most when it does not exists. This example, Array object missing indexOf method, has annoyed me for so long!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 21, 2015 Aug 21, 2015

nicoDuduf wrote:

It seemed to work well, but I found out that it breaks this kind of loop:

  1. for (var i in array) { 
  2.      alert(array); 
  3.      } 

Technically it is not breaking this loop. The loop is just used in a wrong way.

See http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea‌:

"The for-in statement by itself is not a "bad practice", however it can be mis-used, for example, to iterate over arrays or array-like objects.

The purpose of the for-in statement is to enumerate over object properties, this statement will go up in the prototype chain, enumerating also inherited properties, thing that sometimes is not desired."

However, since other script authors may use loops in such a wrong way, using prototype on things like Array or Object in your script might break scripts by other authors.

Hence, as David suggested, you better don't use it. I only use prototype for my own object types.

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 26, 2015 Aug 26, 2015

Thanks for this answer,

I found that, that's why I tried

  1. Object.defineProperty()

with the statement "enumerable:false" which makes for-in loops to not iterate through properties added this way. This could have worked, if only Object.defineProperty was implemented in extendScript.

It is little known that the for-in loop is not meant to iterate through Arrays, and a looooot of developpers use it this way, as it seems quicker than writing the whole "for (i;i<;i++)" loop...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 30, 2015 Aug 30, 2015
LATEST

Also you can write it like this:

for (var i in array) {

     if (array.hasOwnProperty(i)) {

          alert(array);

     }

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines