6

I would like to simulate the C# Any() method, which can be used to determine whether if a collection has any matching objects based on a lambda expression.

I used jQuery's $.grep to make things easier:

Array.prototype.any = function (expr) {

    if (typeof jQuery === 'undefined')
        throw new ReferenceError('jQuery not loaded');

    return $.grep(this, function (x, i) {
        return eval(expr);
    }).length > 0;

};

var foo = [{ a: 1, b: 2 }, { a:1, b: 3 }];

console.log(foo.any('x.a === 1')); //true
console.log(foo.any('x.a === 2')); //false

I know that eval() is bad practice for obvious reasons. But is it ok in this case, since I won't use this with anything related to some user inputs?

Can this be done without eval()? I can't figure out a way to pass an expression to the function without evaluating it.

http://jsfiddle.net/dgGvN/

Johan
  • 35,120
  • 54
  • 178
  • 293

2 Answers2

9

I suggest you take a good look at JS closures. In particular, what you did there can be done natively in JS by using the Array.some method:

[{ a: 1, b: 2 }, { a:1, b: 3 }].some(function(x) { return x.a === 1; }); // true
[{ a: 1, b: 2 }, { a:1, b: 3 }].some(function(x) { return x.a === 2; }); // false

edit: in this case we're not really using closures but rather plain simple anonymous functions...

CAFxX
  • 28,060
  • 6
  • 41
  • 66
5

Pass in a function:

Array.prototype.any = function (expr) {

    if (typeof jQuery === 'undefined')
        throw new ReferenceError('jQuery not loaded');

    return $.grep(this, expr).length > 0;

};

var foo = [{ a: 1, b: 2 }, { a:1, b: 3 }];

console.log(foo.any(function(x, i){return x.a === 1})); //true
console.log(foo.any(function(x, i){return x.a === 2})); //false
Naftali
  • 144,921
  • 39
  • 244
  • 303
  • Thanks. This way it'll work just like the some() method that @CAFxX mentioned (which I obviously didn't know about) – Johan May 14 '13 at 14:02