Skip to content

Commit 18fd1fd

Browse files
committed
Use Map shim with _.uniq
1 parent f77e099 commit 18fd1fd

File tree

1 file changed

+51
-10
lines changed

1 file changed

+51
-10
lines changed

underscore.js

+51-10
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,52 @@
131131
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
132132
};
133133

134+
// A small Map shim, to support the most basic use cases.
135+
var MapShim = function() {
136+
this._values = [];
137+
this._keys = [];
138+
this._primitives = nativeCreate && nativeCreate(null);
139+
this.size = 0;
140+
141+
this._lastKey = void 0;
142+
this._lastIndex = -1;
143+
};
144+
var keyer = function(value) {
145+
return typeof value === 'string' ? 's' + value : value;
146+
};
147+
MapShim.prototype.get = function(key) {
148+
if (this.has(key)) return this._values[this._lastIndex];
149+
};
150+
MapShim.prototype.has = function(key) {
151+
var index = this._indexOf(key);
152+
return index >= 0 && index < this.size;
153+
};
154+
MapShim.prototype.set = function(key, value) {
155+
var index = this._indexOf(key);
156+
157+
this._values[index] = value;
158+
if (index >= this.size) {
159+
this.size = index + 1;
160+
this._keys[index] = key;
161+
if (this._primitives && !_.isObject(key)) this._primitives[keyer(key)] = index;
162+
}
163+
};
164+
MapShim.prototype._indexOf = function(key) {
165+
var index = this._lastIndex;
166+
if (this._lastKey === key && index >= 0) return index;
167+
if (this._primitives && !_.isObject(key)) {
168+
index = this._primitives[keyer(key)];
169+
} else {
170+
index = _.indexOf(this._keys, key);
171+
}
172+
if (index === -1 || index === void 0) index = this.size;
173+
174+
this._lastKey = key;
175+
this._lastIndex = index;
176+
return index;
177+
};
178+
179+
134180
// Collection Functions
135181
// --------------------
136182

@@ -518,21 +564,16 @@
518564
isSorted = false;
519565
}
520566
if (iteratee != null) iteratee = cb(iteratee, context);
521-
var result = [];
522-
var seen = [];
567+
var seen = new MapShim();
568+
var result = seen._values;
523569
for (var i = 0, length = array.length; i < length; i++) {
524570
var value = array[i],
525571
computed = iteratee ? iteratee(value, i, array) : value;
526572
if (isSorted) {
527-
if (!i || seen !== computed) result.push(value);
573+
if (seen !== computed) result.push(value);
528574
seen = computed;
529-
} else if (iteratee) {
530-
if (!_.contains(seen, computed)) {
531-
seen.push(computed);
532-
result.push(value);
533-
}
534-
} else if (!_.contains(result, value)) {
535-
result.push(value);
575+
} else if (!seen.has(computed)) {
576+
seen.set(computed, value);
536577
}
537578
}
538579
return result;

0 commit comments

Comments
 (0)