Skip to content

Commit

Permalink
import code from friendly_args branch to make filter take flexible args
Browse files Browse the repository at this point in the history
  • Loading branch information
ratbeard committed Mar 1, 2010
1 parent 21f5d61 commit c68ec57
Show file tree
Hide file tree
Showing 4 changed files with 888 additions and 2 deletions.
39 changes: 39 additions & 0 deletions test/flexargs.js
@@ -0,0 +1,39 @@
$(document).ready(function() {

module("Flexargs");

test('collections: filter', function() {
var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
equals(evens.join(', '), '2, 4, 6', 'selected each even number');

evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
equals(evens.join(', '), '2, 4, 6', 'aliased as "filter"');

var dogs = [{name: 'bubbles', age: 5}, {name: 'lily', age: 5}, {name: 'ginger', age: 9}]

same(
_.filter(dogs, {age: 5}),
_.filter(dogs, function (dog) { return dog.age == 5; }),
'can filter by passing an object of properties to match');

same(
_.filter(dogs, {age: 5, name: 'lily'}),
_.filter(dogs, function (dog) { return dog.age == 5 && dog.name == 'lily'; }),
'can filter by passing an object of multiple properties to match');

same(
_.filter(dogs, 'age', 5),
_.filter(dogs, function (dog) { return dog.age == 5; }),
'can filter by passing a key and value to match');

same(
_.filter(dogs, 'name', /l/),
_.filter(dogs, function (dog) { return /l/.test(dog.name) }),
'passing a regex as a value calls regex.test()');

same(
_.filter(dogs, {name: /e/, age: 5}),
_.filter(dogs, function (dog) { return /e/.test(dog.name) && dog.age === 5}),
'can pass a regex in an object');
});
});
7 changes: 5 additions & 2 deletions test/test.html
Expand Up @@ -2,13 +2,16 @@
<html>
<head>
<title>Underscore Test Suite</title>
<!-- vendor -->
<link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen" />
<script src="vendor/jquery.js"></script>
<script src="vendor/qunit.js"></script>
<script src="vendor/jslitmus.js"></script>
<script src="../underscore.js"></script>

<script src="underscore.scraps.js"></script>
<!-- code -->
<script src="../underscore.flexargs.js"></script>
<!-- tests -->
<script src="flexargs.js"></script>
</head>
<body>
<h1 id="qunit-header">Underscore Test Suite</h1>
Expand Down
31 changes: 31 additions & 0 deletions underscore.flexargs.js
@@ -0,0 +1,31 @@
// Return all the elements that pass a truth test.
// Delegates to JavaScript 1.6's native filter if available.
//
// TODO:
// abstract out iterator building code
var origFilter = _.filter;

_.filter = function(obj, iterator, context) {
if (!_.isFunction(iterator)) {
if (typeof iterator === 'object') {
// given props to check, e.g. {age: 5, name: 'h' }
// TODO: speed up if only one prop
var expected = iterator, iterator = function (item) {
return _.every(expected, function (value, key) {
return _.isRegExp(value) ? value.test(item[key]) : value === item[key];
});
};
}
else {
// given a key, value pair to check
// can totally ignore context arg as it makes no sense if we are building iterator fn.
var key = iterator, value = context;
iterator = _.isRegExp(value) ?
function(item) { return value.test(item[key]);} :
function(item) { return item[key] === value; };
}
}

return origFilter(obj, iterator, context)

};

0 comments on commit c68ec57

Please sign in to comment.