diff --git a/test/collections.js b/test/collections.js index 3759a6495..516dbf334 100644 --- a/test/collections.js +++ b/test/collections.js @@ -164,5 +164,12 @@ $(document).ready(function() { test('collections: size', function() { equals(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); }); + + test('collections: buildLookup', function() { + same(_.buildLookup([1,'hi']), {1:true, 'hi':true}, 'defaults values to true'); + same(_.buildLookup([1,'hi'], 1), {1:1, 'hi':1}, 'can override value'); + same(_.buildLookup({5:'five'}), {five: true}, 'making a map from an object uses its values'); + }); + }); diff --git a/test/objects.js b/test/objects.js index 272b66ef1..02e00abd1 100644 --- a/test/objects.js +++ b/test/objects.js @@ -11,7 +11,7 @@ $(document).ready(function() { }); test("objects: functions", function() { - var expected = ["alias", "all", "any", "bind", "bindAll", "breakLoop", "clone", "compact", + var expected = ["alias", "all", "any", "bind", "bindAll", "breakLoop", "buildLookup", "clone", "compact", "compose","defer", "delay", "detect", "each", "every", "extend", "filter", "first", "flatten", "foldl", "foldr", "forEach", "functions", "head", "identity", "include", "indexOf", "inject", "intersect", "invoke", "isArguments", "isArray", "isDate", "isElement", "isEmpty", "isEqual", diff --git a/underscore.js b/underscore.js index cce9756a4..6c120a772 100644 --- a/underscore.js +++ b/underscore.js @@ -230,6 +230,24 @@ _.size = function(obj) { return _.toArray(obj).length; }; + + // Build a lookup map from a collection. + // Pay a little memory upfront to make searching a collection for a + // value faster later + // e.g: + // + // var lookup = _.buildLookup([1,2,8]) // {1: true, 2: true, 8: true} + // lookup[key] // instead of: _.include(array, key) + // + // See example usage in #without + // By default sets the value to true, can pass in a value to use instead + _.buildLookup = function (obj, useValue) { + useValue = (useValue === undefined)? true : useValue; + return _.reduce(obj, {}, function (memo, value) { + memo[value] = useValue; + return memo; + }); + }; // -------------------------- Array Functions: ------------------------------ @@ -269,8 +287,8 @@ // Return a version of the array that does not contain the specified value(s). _.without = function(array) { - var values = _.rest(arguments); - return _.select(array, function(value){ return !_.include(values, value); }); + var lookup = _.buildLookup(_.rest(arguments)); + return _.filter(array, function(value){ return !lookup[value]; }); }; // Produce a duplicate-free version of the array. If the array has already