diff --git a/ui (gen4)/features/core.js b/ui (gen4)/features/core.js index ac9c9a9d..75515c71 100755 --- a/ui (gen4)/features/core.js +++ b/ui (gen4)/features/core.js @@ -1516,7 +1516,7 @@ var ChangesActions = actions.Actions({ } changes[section] = (changes[section] || []) .concat(items) - .uniqueStrings() + .unique() this.changes = changes // section(s)... diff --git a/ui (gen4)/imagegrid/data.js b/ui (gen4)/imagegrid/data.js index c87b1a1a..f02a34d6 100755 --- a/ui (gen4)/imagegrid/data.js +++ b/ui (gen4)/imagegrid/data.js @@ -333,8 +333,6 @@ var DataPrototype = { continue } - // try and avoid the expensive .indexOf(..) as much as possible... - //var j = e != order[i] ? order.indexOf(e) : i var j = order_idx[e] if(j >= 0){ @@ -360,8 +358,12 @@ var DataPrototype = { } // avoid duplicating target items... + // XXX not yet sure here what is faster, .toKeys(..) or Set(..) + //var target_idx = target.toKeys() + var target_idx = new Set(target) rest = rest - .filter(function(e){ return target.indexOf(e) < 0 }) + //.filter(function(e){ return e in target_idx }) + .filter(function(e){ return target_idx.has(e) }) if(rest.length > 0){ target.length = Math.max(order.length, target.length) @@ -2964,7 +2966,7 @@ var DataWithTagsPrototype = { // iterate through all the gids (both images and buffer/data) for(var gid in Object.keys(images) .concat(Object.keys(buffer)) - .uniqueStrings()){ + .unique()){ // no tags / remove... if(buffer[gid] == null || buffer[gid].tags.length == 0){ // the image exists and has tags... @@ -2994,7 +2996,7 @@ var DataWithTagsPrototype = { var l = img.tags.length img.tags = img.tags .concat(buffer[gid].tags) - .uniqueStrings() + .unique() // we are updated iff length changed... // NOTE: this is true as we are not removing anything // thus the length can only increase if changes are diff --git a/ui (gen4)/lib/util.js b/ui (gen4)/lib/util.js index d98b463e..d3732a98 100755 --- a/ui (gen4)/lib/util.js +++ b/ui (gen4)/lib/util.js @@ -38,8 +38,7 @@ Object.defineProperty(Object.prototype, 'run', { // // NOTE: this will not compact in-place. Array.prototype.compact = function(){ - return this.filter(function(){ return true }) -} + return this.filter(function(){ return true }) } // Convert an array to object... @@ -63,8 +62,32 @@ Array.prototype.toKeys = function(normalize){ : this.reduce(function(r, e, i){ r[e] = i return r - }, {}) -} + }, {}) } + + +// Convert an array to a map... +// +// This is similar to Array.prototype.toKeys(..) but does not restrict +// value type to string. +// +// Format: +// Map([ +// [, ], +// ... +// ]) +// +// NOTE: this will forget repeating items... +// NOTE: normalize will slow things down... +Array.prototype.toMap = function(normalize){ + return normalize ? + this.reduce(function(m, e, i){ + m.set(normalize(e), i) + return m + }, new Map()) + : this.reduce(function(m, e, i){ + m.set(e, i) + return m + }, new Map()) } // Return an array with duplicate elements removed... @@ -72,22 +95,9 @@ Array.prototype.toKeys = function(normalize){ // NOTE: we are not using an Object as an index here as an Array can // contain any type of item while Object keys can only be strings... // NOTE: for an array containing only strings use a much faster .uniqueStrings(..) +// NOTE: this may not work on IE... Array.prototype.unique = function(normalize){ - if(normalize){ - var cache = this.map(function(e){ return normalize(e) }) - return this.filter(function(e, i, a){ return cache.indexOf(cache[i]) == i }) - - } else { - return this.filter(function(e, i, a){ return a.indexOf(e) == i }) - } -} - - -// Special case of .unique(), allot faster on arrays of strings... -// -// NOTE: this may jield unexpected results for non-string items... -Array.prototype.uniqueStrings = function(normalize){ - return Object.keys(this.toKeys(normalize)) } + return new Array(...(new Set(normalize ? normalize(this) : this))) } // Compare two arrays... @@ -110,6 +120,8 @@ Array.prototype.cmp = function(other){ // Compare two Arrays as sets... // // This will ignore order +// +// XXX should we use Set(..) here??? Array.prototype.setCmp = function(other){ return this === other || this