From 0513f60b63f08636dc0908730c7d4334aa322773 Mon Sep 17 00:00:00 2001
From: Tony Lukasavage
- detect
+ find
- select
+ filter
each, map,
reduce, reduceRight,
- detect, select,
+ find, filter,
reject, all,
any, include,
invoke, pluck,
@@ -312,8 +312,9 @@ var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
=> [4, 5, 2, 3, 0, 1]
- _.detect(list, iterator, [context])
+ _.find(list, iterator, [context])
+ Alias: detect
Looks through each value in the list, returning the first one that
passes a truth test (iterator). The function returns as
@@ -321,20 +322,20 @@ var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
entire list.
-var even = _.detect([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
+var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> 2
- _.select(list, iterator, [context])
- Alias: filter
+ _.filter(list, iterator, [context])
+ Alias: select
Looks through each value in the list, returning an array of all
the values that pass a truth test (iterator). Delegates to the
native filter method, if it exists.
-var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
+var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]
@@ -342,7 +343,7 @@ var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
reject_.reject(list, iterator, [context])
Returns the values in list without the elements that the truth
- test (iterator) passes. The opposite of select.
+ test (iterator) passes. The opposite of filter.
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
@@ -951,7 +952,7 @@ _.clone({name : 'moe'});
_([1,2,3,200]).chain().
- select(function(num) { return num % 2 == 0; }).
+ filter(function(num) { return num % 2 == 0; }).
tap(console.log).
map(function(num) { return num * num }).
value();
From e79586515c5f635650afc32976826e01463dcd1d Mon Sep 17 00:00:00 2001
From: Jeremy Ashkenas
Date: Tue, 18 Oct 2011 16:07:23 -0400
Subject: [PATCH 4/5] Issue #329 -- significant change to _.isEqual semantics.
---
test/objects.js | 12 ++++++------
underscore.js | 41 +++++++++++++++--------------------------
2 files changed, 21 insertions(+), 32 deletions(-)
diff --git a/test/objects.js b/test/objects.js
index c131d920b..5fc4b6a0a 100644
--- a/test/objects.js
+++ b/test/objects.js
@@ -154,8 +154,8 @@ $(document).ready(function() {
ok(_.isEqual({}, {}), "Empty object literals are equal");
ok(_.isEqual([], []), "Empty array literals are equal");
ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal");
- ok(_.isEqual({length: 0}, []), "Array-like objects and arrays are equal");
- ok(_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects");
+ ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal.");
+ ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects");
ok(!_.isEqual({}, []), "Object literals and array literals are not equal");
ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays");
@@ -174,7 +174,7 @@ $(document).ready(function() {
b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null;
// Array elements and properties.
- ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal");
+ ok(!_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are not equal");
a.push("White Rocks");
ok(!_.isEqual(a, b), "Arrays of different lengths are not equal");
a.push("East Boulder");
@@ -183,7 +183,7 @@ $(document).ready(function() {
// Sparse arrays.
ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal");
- ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal");
+ ok(_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are equal when both are empty");
// According to the Microsoft deviations spec, section 2.1.26, JScript 5.x treats `undefined`
// elements in arrays as elisions. Thus, sparse arrays and dense arrays containing `undefined`
@@ -235,8 +235,8 @@ $(document).ready(function() {
// Instances.
ok(_.isEqual(new First, new First), "Object instances are equal");
- ok(_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are equal");
- ok(_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are identical");
+ ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal");
+ ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not identical");
ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined");
// Circular Arrays.
diff --git a/underscore.js b/underscore.js
index d19e26960..5e9d4f3e2 100644
--- a/underscore.js
+++ b/underscore.js
@@ -673,6 +673,8 @@
}
// Ensure that both values are objects.
if (typeA != 'object') return false;
+ // Objects with different constructors are not equal.
+ if (a.constructor !== b.constructor) return false;
// Assume equality for cyclic structures. The algorithm for detecting cyclic structures is
// adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
var length = stack.length;
@@ -684,34 +686,21 @@
// Add the first object to the stack of traversed objects.
stack.push(a);
var size = 0, result = true;
- if (a.length === +a.length || b.length === +b.length) {
- // Compare object lengths to determine if a deep comparison is necessary.
- size = a.length;
- result = size == b.length;
- if (result) {
- // Deep compare array-like object contents, ignoring non-numeric properties.
- while (size--) {
- // Ensure commutative equality for sparse arrays.
- if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
- }
+ // Deep compare objects.
+ for (var key in a) {
+ if (hasOwnProperty.call(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
}
- } else {
- // Deep compare objects.
- for (var key in a) {
- if (hasOwnProperty.call(a, key)) {
- // Count the expected number of properties.
- size++;
- // Deep compare each member.
- if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
- }
- }
- // Ensure that both objects contain the same number of properties.
- if (result) {
- for (key in b) {
- if (hasOwnProperty.call(b, key) && !size--) break;
- }
- result = !size;
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (hasOwnProperty.call(b, key) && !size--) break;
}
+ result = !size;
}
// Remove the first object from the stack of traversed objects.
stack.pop();
From 86eedd2a7b2d02c282ce130c508b0c4f4e494789 Mon Sep 17 00:00:00 2001
From: Jeremy Ashkenas
Date: Tue, 18 Oct 2011 16:51:45 -0400
Subject: [PATCH 5/5] Fixes #335, exporting for Titanium.
---
underscore.js | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/underscore.js b/underscore.js
index 84c966ce3..1cb07d815 100644
--- a/underscore.js
+++ b/underscore.js
@@ -48,13 +48,13 @@
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
- // Export the Underscore object for **CommonJS**, with backwards-compatibility
- // for the old `require()` API. If we're not in CommonJS, add `_` to the
- // global object.
- if (typeof module !== 'undefined' && module.exports) {
- module.exports = _;
- _._ = _;
- } else if (typeof exports !== 'undefined' && exports) {
+ // Export the Underscore object for **Node.js** and **"CommonJS"**, with
+ // backwards-compatibility for the old `require()` API. If we're not in
+ // CommonJS, add `_` to the global object.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
exports._ = _;
} else {
// Exported as a string, for Closure Compiler "advanced" mode.