4

http://jsfiddle.net/SqJ2y/

var list = [
    { mode: 1, type: 'foo', blah: 1 }, 
    { mode: 3, type: 'foo', blah: 1 }, 
    { mode: 3, type: 'foo', blah: 1 },
    { mode: 1, type: 'bar', blah: 1 }, 
    { mode: 2, type: 'bar', blah: 0 },
    { mode: 3, type: 'bar', blah: 1 }
];

var filter = [
    { propertyName: 'mode', value: 1 }, 
    { propertyName: 'type', value: 'foo' },
    { propertyName: 'blah', value: 1 }
];

var i = 0;

var result1 = $.grep(list, function(x){
    i++;
    return x.type === 'foo' && x.mode === 1 && x.blah === 1;
});

console.log(result1, 'iterations:', i); // 6 iterations

var j = 0;

var result2 = list;

$.each(filter, function(k, filter){
    result2 = $.grep(result2, function(listItem) {
        j++;
        return listItem[filter.propertyName] === filter.value;
    });
});

console.log(result2, 'iterations:', j); // 9 iterations

上記のフィルターメソッドを最適化したいと思いますresult2

でわかるようにresult1、より少ない反復で同じ結果を得ることができます。私の例ではあまり見えないかもしれませんが、パフォーマンスが問題になる大きなリストがあります。

result2私の質問: フィルタリングとして機能するようにフィルタリングを最適化する方法はありresult1ますか?

4

3 に答える 3

2

最初に一致するオブジェクトを構築し、それを再利用してループデループを回避できます。

var ob={};
filter.map(function(a,b){
  ob[a.propertyName]=a.value;
})

result2 =  $.grep(list, function(x){
   j++;
   return x.type === ob.tpye && x.mode === ob.mode && x.blah === ob.blah;
});


/* which has the console showing (and yes, they are the same two objects in both results): 
[Object] "iterations:" 6 
[Object] "iterations:" 6   */

フル: http://jsfiddle.net/SqJ2y/2/

于 2013-07-04T10:04:11.777 に答える
0

@dandavis と @Bergi による以前の両方の回答を組み合わせることができます。

var filtered = list.filter(function(item) {
  return filter.every(function(f) {
    return f.value === item[f.propertyName];
  });
});
于 2013-07-04T15:38:36.423 に答える