Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add _.chunk to Array functions. #1919

Closed
wants to merge 11 commits into from
16 changes: 15 additions & 1 deletion test/arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,5 +418,19 @@
deepEqual(_.range(12, 7, -2), [12, 10, 8], 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
deepEqual(_.range(0, -10, -1), [0, -1, -2, -3, -4, -5, -6, -7, -8, -9], 'final example in the Python docs');
});


test('chunk', function() {
deepEqual(_.chunk([], 2), [], 'chunk for empty array returns an empty array');
deepEqual(_.chunk(null, 2), [], 'chunk for null returns an empty array');

deepEqual(_.chunk([1, 2, 3], 0), [], 'chunk into parts of 0 elements returns an empty array');
deepEqual(_.chunk([1, 2, 3], -1), [], 'chunk into parts of negative amount of elements returns an empty array');

deepEqual(_.chunk([1, 2, 3], 3), [[1, 2, 3]], 'chunk into parts of current array length elements returns the original array');
deepEqual(_.chunk([1, 2, 3], 5), [[1, 2, 3]], 'chunk into parts of more then current array length elements returns the original array');

deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 2), [[10, 20], [30, 40], [50, 60], [70]], 'chunk into parts of less then current array length elements');
deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 3), [[10, 20, 30], [40, 50, 60], [70]], 'chunk into parts of less then current array length elements');
});

}());
14 changes: 14 additions & 0 deletions underscore.js
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,20 @@

return range;
};

// Split an **array** into several arrays containing **count** or less elements
// of initial array
_.chunk = function(array, count) {
var result = [];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I wonder if it's faster to compute the length new Array(Math.ceil(array.length / count)) - feel free not to bother with it


if (array == null || count <= 0) return [];

for (var i = 0, lng = array.length; i < lng;) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind using length instead of lng?

result.push(array.slice(i, i += count));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use slice.call(array, i, i+= count) to sidestep overwritten Array#slice and open this up to array-likes.

}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably write line 655-659 as

var i = 0, length = array && array.length, j = 0;
while (i < length && count >= 0) {
     if (i % count) result[j++] = [];
     result[j].push(array[i]);
}

(untested). I would be curious to see some benchmarks


return result;
};

// Function (ahem) Functions
// ------------------
Expand Down