Skip to content

Commit

Permalink
Add a couple new collection methods from Ruby 2.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoglan committed Jun 30, 2013
1 parent 76e9df7 commit c9cea20
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 2 deletions.
17 changes: 17 additions & 0 deletions site/src/pages/enumerable.haml
Expand Up @@ -124,6 +124,23 @@
new Collection(0, false, null).any();
// -> false</pre>
h3. @chunk(block, context)@

Splits the collection into groups of adjacent elements that return the same
value for the block, and returns an array whose elements contain the current
block value and the string of items that returned that value.

<pre>var list = new Collection([3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]);
list.chunk(function(value) { return value % 2 === 0 })

// -> [
// [false, [3, 1]],
// [true, [4]],
// [false, [1, 5, 9]],
// [true, [2, 6]],
// [false, [5, 3, 5]]
// ]
h3. @collect(block, context)@

Alias for @map()@.
Expand Down
12 changes: 12 additions & 0 deletions site/src/pages/hash.haml
Expand Up @@ -281,6 +281,18 @@

Returns @true@ iff the hash contains no data.

h3. @keepIf(predicate, context)@

Deletes all the pairs that do not satisfy the @predicate@ from the hash.
@context@ sets the binding of @this@ within the predicate function. For
example:

<pre>// Remove pairs for California and Illinois
senators.keepIf(function(pair) { return pair.key.code < 'M' });

// senators is now:
// { CA => feinstein, IL => burris }</pre>
h3. @key(value)@

Returns the first key from the hash whose corresponding value is @value@.
Expand Down
11 changes: 11 additions & 0 deletions site/src/pages/set.haml
Expand Up @@ -184,6 +184,17 @@
Returns @true@ iff the receiver is a superset of the set @other@, that is if
all the members of @other@ are also members of the receiver.

h3. @keepIf(predicate, context)@

Removes all the members of the set for which @predicate@ returns @false@.

<pre>var s = new Set([1,2,3,4,5,6,7,8,9]);

// Keep multiples of 3
s.keepIf(function(x) { return x % 3 == 0 });

// s == Set{3,6,9}</pre>
h3. @merge(set)@

Adds all the members of @set@ to the receiver.
Expand Down
28 changes: 26 additions & 2 deletions source/enumerable.js
Expand Up @@ -114,6 +114,29 @@ var Enumerable = new JS.Module('Enumerable', {
return !!truth;
},

chunk: function(block, context) {
if (!block) return this.enumFor('chunk');

var result = [],
value = null,
started = false;

this.forEach(function(item) {
var v = block.apply(context, arguments);
if (started) {
if (Enumerable.areEqual(value, v))
result[result.length - 1][1].push(item);
else
result.push([v, [item]]);
} else {
result.push([v, [item]]);
started = true;
}
value = v;
});
return result;
},

count: function(block, context) {
if (typeof this.size === 'function') return this.size();
var count = 0, object = block;
Expand Down Expand Up @@ -494,6 +517,7 @@ Enumerable.alias({
every: 'all',
findAll: 'select',
filter: 'select',
reduce: 'inject',
some: 'any'
});

Expand Down Expand Up @@ -548,8 +572,8 @@ Enumerable.extend({
this._args = (args || []).slice();
},

// this is largely here to support testing
// since I don't want to make the ivars public
// this is largely here to support testing since I don't want to make the
// ivars public
equals: function(enumerator) {
return JS.isType(enumerator, this.klass) &&
this._object === enumerator._object &&
Expand Down
6 changes: 6 additions & 0 deletions source/hash.js
Expand Up @@ -239,6 +239,12 @@ var Hash = new JS.Class('Hash', {
return true;
},

keepIf: function(block, context) {
return this.removeIf(function() {
return !block.apply(context, arguments);
});
},

key: function(value) {
var result = null;
this.forEach(function(pair) {
Expand Down
6 changes: 6 additions & 0 deletions source/set.js
Expand Up @@ -162,6 +162,12 @@ var Set = new JS.Class('Set', {
return other.isSubset(this);
},

keepIf: function(block, context) {
return this.removeIf(function() {
return !block.apply(context, arguments);
});
},

merge: function(list) {
this.klass.forEach(list, function(item) { this.add(item) }, this);
},
Expand Down
11 changes: 11 additions & 0 deletions test/specs/enumerable_spec.js
Expand Up @@ -124,6 +124,17 @@ JS.ENV.EnumerableSpec = JS.Test.describe(Enumerable, function() { with(this) {
}})
}})

describe("#chunk", function() { with(this) {
before(function() { with(this) {
this.items = list(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5)
}})

it("groups the collection based on changes in the block's return value", function() { with(this) {
assertEqual( [ [false, [3,1]], [true, [4]], [false, [1,5,9,]], [true, [2,6]], [false, [5,3,5]] ],
items.chunk(function(n) { return n % 2 === 0 }) )
}})
}})

describe("#count", function() { with(this) {
before(function() { with(this) {
this.items = list(4,8,2,4,7)
Expand Down

0 comments on commit c9cea20

Please sign in to comment.