किसी स्थिति से मेल खाते हुए किसी सरणी के अंदर ऑब्जेक्ट का इंडेक्स प्राप्त करें


320

मेरे पास एक सरणी है:

[{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"},...]

मैं उस वस्तु का सूचकांक कैसे प्राप्त कर सकता हूं जो किसी स्थिति से मेल खाती है, पूरे सरणी पर पुनरावृत्ति किए बिना?

उदाहरण के लिए, prop2=="yutu"मैं सूचकांक प्राप्त करना चाहता हूं 1

मैंने देखा .indexOf()लेकिन लगता है कि इसका उपयोग सरल सरणियों के लिए किया जाता है जैसे ["a1","a2",...]। मैंने भी जाँच की $.grep()लेकिन यह ऑब्जेक्ट्स को लौटाता है, इंडेक्स को नहीं।

जवाबों:


730

2016 तक, आप इसके लिए Array.findIndex(एक ES2015 / ES6 मानक) का उपयोग करने वाले हैं :

a = [
  {prop1:"abc",prop2:"qwe"},
  {prop1:"bnmb",prop2:"yutu"},
  {prop1:"zxvz",prop2:"qwrq"}];
    
index = a.findIndex(x => x.prop2 ==="yutu");

console.log(index);

यह Google Chrome, Firefox और Edge में समर्थित है। Internet Explorer के लिए, लिंक किए गए पृष्ठ पर एक पॉलीफ़िल है।

प्रदर्शन नोट

फ़ंक्शन कॉल महंगे हैं, इसलिए वास्तव में बड़े सरणियों के साथ एक साधारण लूप इससे बेहतर प्रदर्शन करेगा findIndex:

let test = [];

for (let i = 0; i < 1e6; i++)
    test.push({prop: i});


let search = test.length - 1;
let count = 100;

console.time('findIndex/predefined function');
    let fn = obj => obj.prop === search;

    for (let i = 0; i < count; i++)
        test.findIndex(fn);
console.timeEnd('findIndex/predefined function');


console.time('findIndex/dynamic function');
    for (let i = 0; i < count; i++)
        test.findIndex(obj => obj.prop === search);
console.timeEnd('findIndex/dynamic function');


console.time('loop');
    for (let i = 0; i < count; i++) {
        for (let index = 0; index < test.length; index++) {
            if (test[index].prop === search) {
                break;
            }
        }
    }
console.timeEnd('loop');

अधिकांश अनुकूलन के साथ, यह देखभाल के साथ लागू किया जाना चाहिए और केवल तभी जब वास्तव में जरूरत हो।


3
मैं यहाँ एक अस्थायी सरणी की आवश्यकता नहीं देख रहा हूँ। बस इस तथ्य का उपयोग करें कि पुनरावृत्ति फ़ंक्शन संदर्भ पर बंद हो जाता है और एक चर का उपयोग करता है। इसके अलावा, गैर- jQuery संस्करण काम नहीं करता है (मान लीजिए कि यह सूचकांक में पाया गया है 0?)। दोनों समाधान आवश्यकता से अधिक पुनरावृत्ति करते हैं, जो कि आदर्श से कम है यदि सरणी बड़ी है (हालांकि इसे इतना बड़ा होने की संभावना मानव को कम दिखाई देगी, जब तक कि लुकअप बहुत अधिक नहीं हो रहा है )।
TJ Crowder

@ thg435: अभी भी लगता है कि यह एक रब गोल्डबर्ग मशीन का एक सा है, जहां एक साधारण लीवर ट्रिक करेगा। :-) लेकिन हे, यह काम करता है!
टीजे क्राउडर

4
क्या आप यह बता सकते हैं कि x => x.prop2=="yutu"findIndex () के साथ कैसे काम करता है?
अभय पई

5
@AbhayPai: यह एक ही रूप हैfunction(x) { return x.prop2=="yutu" }
Georg

6
मुझे पॉलीफ़िल का उपयोग करने का सुझाव पसंद है। हालांकि, जैसा कि लिखा गया कोड IE11 में अभी भी एक तीर / लैम्ब्डा फ़ंक्शन के उपयोग के कारण पॉलीफ़िल के साथ विफल रहता है। index = a.findIndex(function (x) { return x.prop2 == "yutu" })इस मुद्दे को फिर से लिखा गया है ताकि पॉलीफ़िल कोड के साथ, findIndex ने IE11 में काम किया
रिक ग्लोस

26

मैं वस्तु tha के सूचकांक को एक शर्त (सरणी के साथ पुनरावृत्ति के बिना) कैसे प्राप्त कर सकता हूं?

आप नहीं कर सकते, कुछ को सरणी के माध्यम से पुनरावृत्त करना है (कम से कम एक बार)।

यदि स्थिति बहुत बदल जाती है, तो आपको लूप के माध्यम से देखना होगा और उसमें मौजूद वस्तुओं को देखना होगा कि क्या वे स्थिति से मेल खाते हैं। हालांकि, ES5 सुविधाओं के साथ एक प्रणाली पर (या यदि आप एक शिम स्थापित करते हैं), कि पुनरावृत्ति काफी संक्षिप्त रूप से की जा सकती है:

var index;
yourArray.some(function(entry, i) {
    if (entry.prop2 == "yutu") {
        index = i;
        return true;
    }
});

वह नए (ईश) Array#someफ़ंक्शन का उपयोग करता है , जो उस ऐरे में प्रविष्टियों के माध्यम से लूप करता है जब तक कि फ़ंक्शन आपको इसे सही नहीं देता। मैंने जो फ़ंक्शन दिया है वह मिलान प्रविष्टि के सूचकांक को बचाता है, फिर trueपुनरावृति को रोकने के लिए वापस लौटता है।

या बेशक, बस एक forलूप का उपयोग करें । आपके विभिन्न पुनरावृत्ति विकल्प इस अन्य उत्तर में शामिल हैं

लेकिन यदि आप हमेशा इस लुकअप के लिए समान प्रॉपर्टी का उपयोग करते हैं, और यदि प्रॉपर्टी वैल्यू अद्वितीय हैं, तो आप सिर्फ एक बार लूप कर सकते हैं और उन्हें मैप करने के लिए ऑब्जेक्ट बना सकते हैं:

var prop2map = {};
yourArray.forEach(function(entry) {
    prop2map[entry.prop2] = entry;
});

(या, फिर से, आप एक forलूप या अपने किसी अन्य विकल्प का उपयोग कर सकते हैं ।)

फिर अगर आपको इसके साथ प्रविष्टि खोजने की आवश्यकता है prop2 = "yutu", तो आप यह कर सकते हैं:

var entry = prop2map["yutu"];

मैं इसे "क्रॉस-इंडेक्सिंग" सरणी कहता हूं। स्वाभाविक रूप से, यदि आप प्रविष्टियाँ हटाते हैं या जोड़ते हैं (या उनके prop2मान बदलते हैं), तो आपको अपनी मैपिंग ऑब्जेक्ट को भी अपडेट करना होगा।


स्पष्टीकरण के लिए धन्यवाद! JQuery के साथ समाधान thg435मैं क्या चाहता था द्वारा इंगित किया गया ...
amp

21

टीजे क्राउडर ने क्या कहा, हर मार्ग में किसी न किसी प्रकार की छिपी हुई पुनरावृत्ति होगी, जो इस स्थान पर बनेगी :

var index = _.findIndex(array, {prop2: 'yutu'})

1
जब आप सूचकांक प्राप्त करने के लिए विभिन्न तरीकों से बस लूप कर सकते हैं, तो इंडेक्स सबसे अच्छा समाधान है, यहां तक ​​कि ईएस 6 में देशी सरणी विधियों में अपनाया गया है
केली मिलिगन

13
var CarId = 23;

//x.VehicleId property to match in the object array
var carIndex = CarsList.map(function (x) { return x.VehicleId; }).indexOf(CarId);

और मूल सरणी संख्या के लिए आप यह भी कर सकते हैं:

var numberList = [100,200,300,400,500];
var index = numberList.indexOf(200); // 1

अगर आपको एरे में कोई मान नहीं मिल रहा है तो आपको -1 मिलेगा।


11
var index;
yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' ? (index = i, true) : false;
});

सरणी के सभी तत्वों पर Iterate करें। यह या तो सूचकांक और सही या गलत पर वापस लौटता है यदि शर्त मेल नहीं खाती है।

महत्वपूर्ण सच का स्पष्ट वापसी मूल्य है (या एक मूल्य जो बूलियन परिणाम सच है)। एकल असाइनमेंट पर्याप्त नहीं है, क्योंकि 0 (बूलियन (0) === असत्य) के साथ एक संभावित सूचकांक है, जो एक त्रुटि का परिणाम नहीं होगा, लेकिन पुनरावृत्ति के विघटन को अक्षम करता है।

संपादित करें

उपरोक्त का एक छोटा संस्करण:

yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' && ~(index = i);
});

आपके दूसरे स्निपेट में ~ चरित्र क्या करता है?
सीरकन

@serkan, यह एक बिटवाइज़ नहीं| ऑपरेटर है, यह एक इंडेक्स (-1) के साथ एक सचाई / गलत परिणाम से प्राप्त करने का एक छोटा संस्करण है , यदि कोई इंडेक्स मौजूद है।
नीना शुल्ज़

धन्यवाद नीना, बिना ~ चरित्र, कोड के रूप में काम करता है, है ना?
सेरकन

@serkan, आपका प्रश्न स्पष्ट नहीं है, लेकिन इसके बिना ~यह काम नहीं करता है।
नीना शुल्ज़

1
ओह, !!(index = 0)और !!~(index = 0)अंतर वास्तव में। धन्यवाद!
सीरकन

4

आप Array.prototyp.some () निम्नलिखित तरीके से उपयोग कर सकते हैं (जैसा कि अन्य उत्तरों में वर्णित है):

https://jsfiddle.net/h1d69exj/2/

function findIndexInData(data, property, value) {
    var result = -1;
    data.some(function (item, i) {
        if (item[property] === value) {
            result = i;
            return true;
        }
    });
    return result;
}
var data = [{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"}]



alert(findIndexInData(data, 'prop2', "yutu")); // shows index of 1

4

मैंने उपरोक्त कई समाधान देखे हैं।

यहाँ मैं अरेंज ऑब्जेक्ट में सर्च टेक्स्ट के इंडेक्स को खोजने के लिए मैप फंक्शन का उपयोग कर रहा हूँ।

मैं छात्रों के डेटा का उपयोग करने के साथ अपने उत्तर की व्याख्या करने जा रहा हूं।

  • चरण 1 : छात्रों के लिए ऐरे ऑब्जेक्ट बनाएं (वैकल्पिक आप अपनी ऐरे ऑब्जेक्ट बना सकते हैं)।
    var students = [{name:"Rambabu",htno:"1245"},{name:"Divya",htno:"1246"},{name:"poojitha",htno:"1247"},{name:"magitha",htno:"1248"}];

  • चरण 2 : खोज पाठ के लिए चर बनाएं
    var studentNameToSearch = "Divya";

  • चरण 3 : मिलान किए गए इंडेक्स को स्टोर करने के लिए वैरिएबल बनाएं (यहां हम मैप फंक्शन का इस्तमाल करने के लिए उपयोग करते हैं)।
    var matchedIndex = students.map(function (obj) { return obj.name; }).indexOf(studentNameToSearch);

var students = [{name:"Rambabu",htno:"1245"},{name:"Divya",htno:"1246"},{name:"poojitha",htno:"1247"},{name:"magitha",htno:"1248"}];

var studentNameToSearch = "Divya";

var matchedIndex = students.map(function (obj) { return obj.name; }).indexOf(studentNameToSearch);

console.log(matchedIndex);

alert("Your search name index in array is:"+matchedIndex)


3
function findIndexByKeyValue(_array, key, value) {
    for (var i = 0; i < _array.length; i++) { 
        if (_array[i][key] == value) {
            return i;
        }
    }
    return -1;
}
var a = [
    {prop1:"abc",prop2:"qwe"},
    {prop1:"bnmb",prop2:"yutu"},
    {prop1:"zxvz",prop2:"qwrq"}];
var index = findIndexByKeyValue(a, 'prop2', 'yutu');
console.log(index);

1

आप वास्तव में पुनरावृति क्यों नहीं करना चाहते हैं? नए Array.prototype.forEach इस उद्देश्य के लिए बहुत अच्छे हैं!

यदि आप चाहें तो एक एकल विधि कॉल के माध्यम से खोजने के लिए आप एक बाइनरी सर्च ट्री का उपयोग कर सकते हैं। यह जेएस में बीट्री और रेड ब्लैक सर्च ट्री का एक अच्छा कार्यान्वयन है - https://github.com/vadimg/js_bintrees - लेकिन मुझे यकीन नहीं है कि आप एक ही समय में इंडेक्स पा सकते हैं।


1

Array.reduce () का उपयोग कर एक कदम - कोई jQuery नहीं

var items = [{id: 331}, {id: 220}, {id: 872}];

var searchIndexForId = 220;
var index = items.reduce(function(searchIndex, item, index){
  if(item.id === searchIndexForId) { 
    console.log('found!');
    searchIndex = index;
  }
  return searchIndex;
}, null);

nullयदि इंडेक्स नहीं मिला तो वापस आ जाएगा ।



0

जॉर्ज ने पहले ही उल्लेख किया है कि ES6 के पास इसके लिए Array.findIndex है। और कुछ अन्य जवाब Array.some पद्धति का उपयोग करके ES5 के लिए समाधान हैं।

एक और अधिक सुंदर दृष्टिकोण हो सकता है

var index;
for(index = yourArray.length; index-- > 0 && yourArray[index].prop2 !== "yutu";);

उसी समय मैं जोर देना चाहूंगा, Array.some को बाइनरी या अन्य कुशल खोज तकनीक के साथ लागू किया जा सकता है। तो, यह कुछ ब्राउज़र में लूप के लिए बेहतर प्रदर्शन कर सकता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.