Remove duplicate words from filenames (JScript array.indexOf error)

I am trying to write a Rename Script to remove duplicate words from filenames:

function OnGetNewName(getNewNameData)
{
    var splitby = " ";
    var joinwith = " ";
    var ArrOld = getNewNameData.newname.split(splitby);
    var ArrNew = [];

    for (var i = 0; i < ArrOld.length; i++)
    {
        if (ArrNew.indexOf(ArrOld[i]) == -1)   //   <--  trouble here!
        {
            ArrNew.push(ArrOld[i]);
        }
    }

    return ArrNew.join(joinwith);
}

I am rather confident the code is ok, but I keep getting errors:

Error at line 10, position 9
Object doesn't support this property or method (0x800a01b6)

Tested on Win7 and Win10. I googled the error code, but couldn't find anything relevant. indexOf is supported, right?

Is this something deeper or am I just missing a typo?

JScript arrays don't seem to support the indexOf method like JavaScript arrays do.

See e.g. https://stackoverflow.com/questions/26073853/js-file-doesnt-work.

The suggestion there is to roll your own function:

function arrayContains(array, value){
    for (var i = 0, e = array.length; i < e; ++i) {
        if (array[i] === value) {
            return true;
        }
    }
    return false;
}
2 Likes

Here's an alternative version which uses the StringSet object provided by Opus, reducing the amount of code.

(In general, searching a set is usually more efficient than searching an array. In this case it won't make any real difference as filenames will only contain a handful of words. But it still makes things easier.)

Another difference is that the word matching is done case-insensitive (moo = Moo etc.).

If you want it to be case-sensitive, change DOpus.Create.StringSetI() to DOpus.Create.StringSet().

It also takes care of file extensions by using the built-in properties to split the stem and extension. (The original script would turn moo moo moo.txt into moo moo.txt as it saw the last word as moo.txt. The script below takes care of that.)

function OnGetNewName(getNewNameData)
{
    var splitby = " ";
    var joinwith = " ";
    var ArrOld = getNewNameData.newname_stem_m.split(splitby);
	var SetUnique = DOpus.Create.StringSetI();
    var ArrNew = [];

    for (var i = 0; i < ArrOld.length; i++)
    {
        if (SetUnique.insert(ArrOld[i]))
        {
            ArrNew.push(ArrOld[i]);
        }
    }

    return ArrNew.join(joinwith) + getNewNameData.newname_ext_m;
}
3 Likes

Thanks. Very elegant solution! I stumbled upon the file extension problem when testing the original version, I had assumed the Ignore extension option had stripped it. Another thing learned :slight_smile:

Could you please add this to the stringset docs StringSet [Directory Opus Manual]

It’s already documented.

But not properly, that's why I had to search the forums

It should be mentioned in the set, how would a reader know to click on the factory to learn that case sensitivity is set via a different name?

How else would you know how to create a StringSet at all? You have to go there to make one, at which point it tells you how to choose which one you make.

No you don't, changing "DOpus.Create.Vector()" to "DOpus.Create.StringSet()" is a simple and intuitive replacement not requiring any docs