2013-06-13 25 views
11

Nesnelerin özelliklerine göre nesneleri seçmek istiyorum, ancak her zaman aynı özellikler değil.Değişken parametrelerle bir javascript nesne dizilimi filtreleme

arr = [ 
    { name: "joe", age21: 1 }, 
    { name: "nick", age21: 0 }, 
    { name: "blast", age21: 1 } 
]; 

arr.filter(function(item) { 
    return (item.name === "nick" && item.age21 === 1); 
}); 

Ama bazen de örneğin adına göre filtreleme istiyorum: Bir başka deyişle parametrelerin listesini işleve geçirilen böylece Ne yapmak istiyorum bu genelleme olduğunu

arr.filter(function(item) { 
    return (item.name === "nick"); 
}); 

. Ben aşağıdaki ile geldim, ama yavaş ve daha iyi bir yolu olup olmadığını merak ediyorum: filterParams(arr, {name: "nick", age21: 1});

veya:

filterParams = function(arr, params) { 
    var new_array = arr.filter(function(item) { 
     var select = 1 
     for(obj in params) { //create the filter criteria based on varying set of parameters 
      var select = select && params[obj] === item[obj]; 
     } 
     return select; 
    }); 
    return new_array; 
} 

Sonra birlikte diyebiliriz filterParams(arr, {name: "nick"});

ve her iki şekilde çalışır.

Merak ediyorsanız, bunu yapıyorum çünkü farklı veri kümeleriyle aynı rutinde çalışmak istiyorum, bu nedenle filtre özelliklerinin genelleştirilmesi gerekir, böylece her birine özgü özelliklere filtre uygulayabilirim Veri kümesi.

Teşekkürler!

function filter(arr, criteria) { 
    return arr.filter(function(obj) { 
    return Object.keys(criteria).every(function(c) { 
     return obj[c] == criteria[c]; 
    }); 
    }); 
} 

Örneğin:

+0

* "ama yavaş" Bunu ölçmek nasıl oldu *? Kaç elemandan bahsediyoruz? Kodu zaten 'obj' yerel yaparak, global değil ve zaten bir uyumsuzluk olduğunda (yani, döngüden çıkmışsa) özellikleri karşılaştırmayı durdurarak geliştirebilirsiniz. Bu soruyu, sadece kodunuzu geliştirmek istiyorsanız http://codereview.stackexchange.com/ için daha uygun olabilir. –

+0

Kutsal sh * t karmaşık görünen topları. Bunu yapmak istediğine emin misin? Neden sadece bir 'filter_by_name' ve 'filter_by_age 've' filter_by_age_and_name' yazmıyor (ya da onları zincirlenebilir hale getiriyor). Bu, bir erken optimizasyon vakasına benziyor. – Halcyon

+0

Oh, bu başarısız olursa bozmak iyi bir fikirdir. Sanırım bunu duydum çünkü standart bir uygulama yapmak için bir yol olmalı gibi görünüyor, ama ne olduğunu bilmiyorum. Oraya taşıyacağım. Teşekkürler! – potterzot

cevap

35

Burada nesne verilen özelliklerin herhangi numaraları için çalışması gerektiğini fonksiyonel bir yaklaşım

var arr = [ 
    { name: 'Steve', age: 18, color: 'red' }, 
    { name: 'Louis', age: 21, color: 'blue' }, //* 
    { name: 'Mike', age: 20, color: 'green' }, 
    { name: 'Greg', age: 21, color: 'blue' }, //* 
    { name: 'Josh', age: 18, color: 'red' } 
]; 

console.log(filter(arr, { age: 21, color: 'blue' })); 
//^ {age:21, color:'blue', name:'Louis} 
// {age:21, color:'blue', name:'Greg'} 

emin değil performans sorunu hakkında, ama bu sorun olmaz. Sen, düzenli ifadeler ile bu daha güçlü böyle bir şey yapabilir:

Düzenleme

function filter(arr, criteria) { 
    return arr.filter(function(obj) { 
    return Object.keys(criteria).every(function(c) { 
     return new RegExp(criteria[c]).test(obj[c]); 
    }); 
    }); 
} 

console.log(filter(arr, { age: /^2\d$/, color: /^(red|blue)$/ })); 
//^ Louis, Greg    --^-- twenty-something 
//            ----^---- red OR blue