विशेषताओं के आधार पर ऑब्जेक्ट ऐरे को कैसे फ़िल्टर करें?


472

मेरे पास अचल संपत्ति की वस्तुओं की निम्नलिखित जावास्क्रिप्ट सरणी है:

var json = {
    'homes': [{
            "home_id": "1",
            "price": "925",
            "sqft": "1100",
            "num_of_beds": "2",
            "num_of_baths": "2.0",
        }, {
            "home_id": "2",
            "price": "1425",
            "sqft": "1900",
            "num_of_beds": "4",
            "num_of_baths": "2.5",
        },
        // ... (more homes) ...     
    ]
}

var xmlhttp = eval('(' + json + ')');
homes = xmlhttp.homes;

मैं जो करना चाहूंगा वह "घर" वस्तुओं का सबसेट वापस करने के लिए ऑब्जेक्ट पर एक फिल्टर करने में सक्षम है।

उदाहरण के लिए, मैं के आधार पर फिल्टर करने के लिए सक्षम होना चाहते हैं: price, sqft, num_of_beds, और num_of_baths

मैं जावास्क्रिप्ट में कुछ कैसे कर सकता हूं जैसे नीचे छद्म कोड:

var newArray = homes.filter(
    price <= 1000 & 
    sqft >= 500 & 
    num_of_beds >=2 & 
    num_of_baths >= 2.5 );

ध्यान दें, सिंटैक्स को ऊपर की तरह होना जरूरी नहीं है। यह सिर्फ एक उदाहरण है।



3
var json = { ... }JSON डेटा विनिमय के लिए एक पाठीय संकेतन है(यहाँ और अधिक।) यदि आप जावास्क्रिप्ट स्रोत कोड के साथ काम कर रहे हैं, और एक स्ट्रिंग के साथ काम नहीं कर रहे हैं, तो आप JSON के साथ काम नहीं कर रहे हैं।
TJ Crowder

1
Eval का उपयोग न करें। यह आमतौर पर बुरा अभ्यास है और प्रदर्शन के मुद्दों का कारण बन सकता है। हमें सिर्फ एक प्रोजेक्ट पर उन लोगों के झुंड से छुटकारा पाना था क्योंकि प्रोसेसर बंद था।
SDH

जवाबों:


717

आप Array.prototype.filterविधि का उपयोग कर सकते हैं :

var newArray = homes.filter(function (el) {
  return el.price <= 1000 &&
         el.sqft >= 500 &&
         el.num_of_beds >=2 &&
         el.num_of_baths >= 2.5;
});

लाइव उदाहरण:

यह विधि नए ECMAScript 5 वें संस्करण मानक का हिस्सा है , और इसे लगभग सभी आधुनिक ब्राउज़रों पर पाया जा सकता है।

IE के लिए, आप संगतता के लिए निम्न विधि को शामिल कर सकते हैं:

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun /*, thisp*/) {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
      if (i in this) {
        var val = this[i];
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }
    return res;
  };
}

8
क्या है / *, itp * /?
Jrereig

2
@ जेरेगिग: यह इंगित करने के लिए एक टिप्पणी है कि एक वैकल्पिक तर्क पारित किया जा सकता है, तर्क को सीधे निर्दिष्ट नहीं किया जाता है क्योंकि ईसीएमए मानक ठीक कहता है कि इस विधि से केवल एक तर्क ( Array.prototype.filter.length == 1;) की उम्मीद करनी चाहिए । जब आप दूसरे तर्क का उपयोग करते हैं, तो इसका उपयोग thisकॉलबैक फ़ंक्शन के अंदर मान के रूप में किया जाएगा ।
CMS

1
@ CMS, क्या आपको यकीन है कि यह कोड काम करता है? यह एक खाली सरणी लौटा रहा है, यहां तक ​​कि जब मैं वास्तव में उच्च होने के लिए मूल्य निर्धारित करता हूं और वास्तव में कम होने के लिए वर्ग / बिस्तर / स्नान। क्या आप सुनिश्चित हैं कि यह कोड काम करता है?
Jrereig

2
@JGreig: हां, यह काम करता है, आपको अपने मानदंडों की जांच करनी चाहिए, हो सकता है कि आप pastie.org या jsbin.com में अपने JSON का एक और पूरा उदाहरण पोस्ट कर सकें और जो मानदंड आप फ़िल्टर करने के लिए उपयोग कर रहे हैं, इसलिए मैं आपकी बेहतर मदद कर सकता हूं।
CMS

2
@ सीएमएस अच्छा होगा यदि उत्तर में यह तथ्य शामिल हो कि एक नया सरणी वापस आ गया है, मूल सरणी को संशोधित नहीं किया गया है। हालांकि यह प्रदान की गई कड़ी में कहा गया है, मुझे लगता है कि इसके बिना जवाब अधूरा या गलत है
GWorking

29

आप jLinq जैसे ढांचे का उपयोग करने की कोशिश कर सकते हैं - jLinq का उपयोग करने का एक कोड नमूना निम्नलिखित है

var results = jLinq.from(data.users)
.startsWith("first", "a")
.orEndsWith("y")
.orderBy("admin", "age")
.select();

अधिक जानकारी के लिए आप लिंक का अनुसरण कर सकते हैं http://www.hugoware.net/projects/jlinq


26

मैं अंडरस्कोर फ्रेमवर्क पसंद करता हूं। यह वस्तुओं के साथ कई उपयोगी संचालन का सुझाव देता है। आपका कार्य:

var newArray = homes.filter(
    price <= 1000 & 
    sqft >= 500 &
    num_of_beds >=2 & 
    num_of_baths >= 2.5);

जैसे अधिलेखित किया जा सकता है:

var newArray = _.filter (homes, function(home) {
    return home.price<=1000 && sqft>=500 && num_of_beds>=2 && num_of_baths>=2.5;
});

आशा है कि यह आपके लिए उपयोगी होगा!


यह अंडरस्कोर चीज़ कैसे काम करती है और वास्तव में इसका क्या मतलब है?
जॉन डेमेट्रियो

4
बस खोज की गई underscore-query( github.com/davidgtonge/underscore-query ) जो जावास्क्रिप्ट स्क्रिप्ट को क्वेरी करने के लिए MongoDB जैसे सिंटैक्स का उपयोग करती है। तो यहाँ आप उपयोग करेंगे_.query(homes, {price: {$lt:1000}, sqft: {$gte: 500}, num_of_beds: {$gte:2}, num_of_baths: {$gte: 2.5}}
प्रोटोटाइप

12

मुझे आश्चर्य है कि किसी ने भी एक-पंक्ति प्रतिक्रिया पोस्ट नहीं की:

const filteredHomes = json.homes.filter(x => x.price <= 1000 && x.sqft >= 500 && x.num_of_beds >=2 && x.num_of_baths >= 2.5);

... और बस इसलिए आप इसे आसानी से पढ़ सकते हैं:

const filteredHomes = json.homes.filter( x => 
  x.price <= 1000 && 
  x.sqft >= 500 && 
  x.num_of_beds >=2 && 
  x.num_of_baths >= 2.5
);

2
शायद इसलिए कि यह सीएमएस के तीर के कार्यों के जवाब के समान ही है
एरिक

11

यहाँ वर्किंग फिडेल है जो jquery MAP फ़ंक्शन का उपयोग करके IE8 में ठीक काम करता है

http://jsfiddle.net/533135/Cj4j7/

json.HOMES = $.map(json.HOMES, function(val, key) {
    if (Number(val.price) <= 1000
            && Number(val.sqft) >= 500
            && Number(val.num_of_beds) >=2
            && Number(val.num_of_baths ) >= 2.5)
        return val;
});

7

JQuery 1.0 से आप jQuery.grep () का उपयोग कर सकते हैं:

$.grep(homes, function (h) {
  return h.price <= 1000
    && h.sqft >= 500
    && h.num_of_beds >= 2
    && h.num_of_baths >= 2.5
});

7

आप इसे बहुत आसानी से कर सकते हैं - संभवतः कई कार्यान्वयन हैं जिन्हें आप चुन सकते हैं, लेकिन यह मेरा मूल विचार है (और शायद कुछ प्रारूप है जहाँ आप jQuery के साथ किसी वस्तु पर पुनरावृति कर सकते हैं, मैं अभी इसके बारे में नहीं सोच सकता):

function filter(collection, predicate)
{
    var result = new Array();
    var length = collection.length;

    for(var j = 0; j < length; j++)
    {
        if(predicate(collection[j]) == true)
        {
             result.push(collection[j]);
        }
    }

    return result;
}

और फिर आप इस फ़ंक्शन को इस तरह से लागू कर सकते हैं:

filter(json, function(element)
{
    if(element.price <= 1000 && element.sqft >= 500 && element.num_of_beds > 2 && element.num_of_baths > 2.5)
        return true;

    return false;
});

इस तरह, आप जो भी परिभाषित करते हैं, उसके आधार पर फ़िल्टर को लागू कर सकते हैं या छोटे फ़िल्टर का उपयोग करके कई बार फ़िल्टर कर सकते हैं।


कृपया पहली स्निपेट में "int लंबाई" को "var length" बदलें
मलय देसाई

4

आप स्वयं एक फ़िल्टर विधि लागू कर सकते हैं जो आपकी आवश्यकताओं को पूरा करती है, यहां बताया गया है:

function myfilter(array, test){
    var passedTest =[];
    for (var i = 0; i < array.length; i++) {
       if(test( array[i]))
          passedTest.push(array[i]);
    }

    return passedTest;
}

var passedHomes = myfilter(homes,function(currentHome){
     return ((currentHome.price <= 1000 )&& (currentHome.sqft >= 500 )&&(currentHome.num_of_beds >=2 )&&(currentHome.num_of_baths >= 2.5));
});

आशा है ये मदद करेगा!


मेरी भविष्यवाणी की स्थिति विभिन्न onclicks से बदलती है। जब भी मैं चाहता हूं कि वर्तमान विधेय मूल्यों को कैसे संग्रहीत किया जा सकता है और इसे myfilter फ़ंक्शन पर लागू किया जा सकता है?
मलय देसाई

3

आपको OGX.List को देखना चाहिए जो फ़िल्टरिंग विधियों में बनाया गया है और मानक जावास्क्रिप्ट सरणी (और समूहन, सॉर्टिंग और खोज भी) को विस्तारित करता है। यहां उन ऑपरेटरों की सूची दी गई है जो फ़िल्टर के लिए समर्थन करते हैं:

'eq' //Equal to
'eqjson' //For deep objects, JSON comparison, equal to
'neq' //Not equal to
'in' //Contains
'nin' //Doesn't contain
'lt' //Lesser than
'lte' //Lesser or equal to
'gt' //Greater than
'gte' //Greater or equal to
'btw' //Between, expects value to be array [_from_, _to_]
'substr' //Substring mode, equal to, expects value to be array [_from_, _to_, _niddle_]
'regex' //Regex match

आप इसे इस तरह से उपयोग कर सकते हैं

  let list = new OGX.List(your_array);
  list.addFilter('price', 'btw', 100, 500);
  list.addFilter('sqft', 'gte', 500);
  let filtered_list = list.filter();

या इस तरह से भी

  let list = new OGX.List(your_array);
  let filtered_list = list.get({price:{btw:[100,500]}, sqft:{gte:500}});

या एक लाइनर के रूप में

   let filtered_list = new OGX.List(your_array).get({price:{btw:[100,500]}, sqft:{gte:500}});

2

या आप बस उपयोग कर सकते हैं $.each(जो कि वस्तुओं के लिए भी काम करता है, न केवल सरणियाँ) और ऐसा ही एक नया सरणी बनाएँ:

var json = {
    'homes': [{
            "home_id": "1",
            "price": "925",
            "sqft": "1100",
            "num_of_beds": "2",
            "num_of_baths": "2.0",
        }, {
            "home_id": "2",
            "price": "1425",
            "sqft": "1900",
            "num_of_beds": "4",
            "num_of_baths": "2.5",
        },
        // ... (more homes) ...     
        {
            "home_id": "3-will-be-matched",
            "price": "925",
            "sqft": "1000",
            "num_of_beds": "2",
            "num_of_baths": "2.5",
        },
    ]
}

var homes = [];
$.each(json.homes, function(){
    if (this.price <= 1000
        && this.sqft >= 500
        && this.num_of_beds >= 2
        && this.num_of_baths >= 2.5
    ) {
        homes.push(this);
    }
});

2

मैं विशिष्ट अवांछित संपत्ति मूल्यों केruleOut आधार पर वस्तुओं को छानने के लिए अपने कार्य का उपयोग करता हूं मैं समझता हूं कि आपके उदाहरण में आप मानों के बजाय शर्तों का उपयोग करना चाहते हैं, लेकिन मेरा उत्तर प्रश्न शीर्षक के लिए मान्य है, इसलिए मैं यहां अपना तरीका छोड़ना चाहूंगा।

function ruleOut(arr, filterObj, applyAllFilters=true) {    
    return arr.filter( row => {            
        for (var field in filterObj) {
            var val = row[field];
            if (val) {                    
                if (applyAllFilters && filterObj[field].indexOf(val) > -1) return false;                
                else if (!applyAllFilters) {                        
                    return filterObj[field].filter(function(filterValue){ 
                        return (val.indexOf(filterValue)>-1);
                    }).length == 0;                 
                }
            }
        }
        return true;
    });
}

कहो कि आपके पास इस तरह के अभिनेताओं की एक सूची है:

let actors = [
  {userName:"Mary", job:"star", language:"Turkish"},
  {userName:"John", job:"actor", language:"Turkish"},
  {userName:"Takis", job:"star", language:"Greek"},
  {userName:"Joe", job:"star", language:"Turkish"},
  {userName:"Bill", job:"star", language:"Turkish"}
];

और आप उन सभी अभिनेताओं को ढूंढना चाहेंगे जिन्हें होलीवुड सितारों के रूप में दर्जा दिया गया है, उनकी राष्ट्रीयता 'अंग्रेजी', 'इटालियन', 'स्पेनिश', 'ग्रीक' में से एक नहीं होनी चाहिए, साथ ही उनका नाम 'मैरी' में से एक नहीं होगा, 'जो'। Bizzar उदाहरण, मुझे पता है! वैसे भी, स्थितियों के उस सेट के साथ आप निम्नलिखित वस्तु बनाएँगे:

let unwantedFieldsFilter= { 
  userName: ['Mary', 'Joe'],    
  job: ['actor'],   
  language: ['English', 'Italian', 'Spanish', 'Greek']  
};

ठीक है, अब यदि आप ruleOut(actors, unwantedFieldsFilter)केवल प्राप्त करेंगे

[{उपयोगकर्ता नाम: "बिल", नौकरी: "स्टार", भाषा: "तुर्की"}]

और बिल आपका आदमी है, क्योंकि उसका नाम 'मैरी', 'जो' में से एक नहीं है, उसकी राष्ट्रीयता ['अंग्रेजी', 'इटालियन', 'स्पेनिश', 'ग्रीक'] प्लस में शामिल नहीं है और वह एक स्टार है!

मेरी विधि में एक विकल्प है, जो applyAllFiltersडिफ़ॉल्ट रूप से सही है और है। यदि आप इस परम के साथ नियत करने की कोशिश करेंगे कि यह झूठा है, तो यह 'और' के बजाय 'या' फ़िल्टरिंग के रूप में काम करेगा। उदाहरण: ruleOut(actors, {job:["actor"], language:["Italian"]}, false)आपको हर कोई मिलेगा जो अभिनेता या इतालवी नहीं है:

[{उपयोगकर्ता नाम: "मैरी", नौकरी: "स्टार", भाषा: "तुर्की"},
{उपयोगकर्ता नाम: "तकि", नौकरी: "स्टार", भाषा: "ग्रीक"},
{उपयोगकर्ता नाम: "जो", नौकरी: "स्टार", भाषा: "तुर्की"},
{उपयोगकर्ता नाम: "बिल", नौकरी: "स्टार", भाषा: "स्टार"]]


1
var filterHome = homes.filter(home =>
  return (home.price <= 999 &&
         home.num_of_baths >= 2.5 &&
         home.num_of_beds >=2 &&
         home.sqft >= 998));
console.log(filterHome);

आप इस लैम्ब्डा फ़ंक्शन का उपयोग कर सकते हैं। अधिक विवरण यहां पाया जा सकता है क्योंकि हम आपके आधार पर डेटा को फ़िल्टर कर रहे हैं जो आपके पास शर्त है जो सही या गलत है और यह विभिन्न सरणी में डेटा एकत्र करेगा ताकि आपका वास्तविक सरणी संशोधित न हो।

@Jrereig कृपया इसे देखें।


1
const x = JSON.stringify(data);
const y = 'search text';

const data = x.filter(res => {
        return(JSON.stringify(res).toLocaleLowerCase()).match(x.toLocaleLowerCase());
      });

0
const state.contactList = [{
    name: 'jane',
    email: 'jane@gmail.com'
  },{},{},...]

const fileredArray = state.contactsList.filter((contactItem) => {
  const regex = new RegExp(`${action.payload}`, 'gi');
  return contactItem.nameProperty.match(regex) || 
    contactItem.emailProperty.match(regex);
});


// contactList: all the contacts stored in state
// action.payload: whatever typed in search field
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.