वस्तुओं की एक सरणी में, किसी वस्तु के सूचकांक को खोजने के लिए सबसे तेज़ तरीका है जिसकी विशेषताएं एक खोज से मेल खाती हैं


135

मैं यह करने के लिए एक कुशल तरीका खोजने के लिए एक छोटी सी कोशिश कर रहा हूँ, लेकिन कहीं नहीं मिला है। मेरे पास वस्तुओं का एक समूह है जो इस तरह दिखता है:

array[i].id = some number;
array[i].name = some name;

मैं क्या करना चाहता हूँ वस्तुओं के सूचकांक को खोजने के लिए जहां आईडी के बराबर है, उदाहरण के लिए, 0,1,2,3 में से एक या 4. मुझे लगता है कि मैं कुछ ऐसा कर सकता था:

var indexes = [];
for(i=0; i<array.length; i++) {
  (array[i].id === 0) ? { indexes[0] = i }
  (array[i].id === 1) ? { indexes[1] = i }
  (array[i].id === 2) ? { indexes[2] = i }
  (array[i].id === 3) ? { indexes[3] = i }
  (array[i].id === 4) ? { indexes[4] = i }
}

हालांकि यह काम करेगा, यह काफी महंगा और धीमा लग रहा है (बदसूरत का उल्लेख नहीं करना), खासकर अगर array.length बड़ी हो सकती है। कैसे थोड़ा इसे सजाना पर कोई विचार? मैंने किसी तरह array.indexOf का उपयोग करने के बारे में सोचा, लेकिन मैं यह नहीं देखता कि वाक्य रचना को कैसे मजबूर किया जाए। यह

array.indexOf(this.id === 0);

उदाहरण के लिए, अपरिभाषित रिटर्न, जैसा कि शायद यह होना चाहिए। अग्रिम में धन्यवाद!


1
यदि आपके पास एक सादा पुराना सरणी है, तो आप केवल इतना ही कर सकते हैं। यही कारण है कि सरणी सूचकांक द्वारा आदेशित वस्तुओं का एक समूह है।
डेव न्यूटन

2
बस आज इस पोस्ट पर आते हैं, सभी लेटकॉमर्स के लिए Array.prototype.findIndex()ECMAScript 2015 में एक नई सरणी विधि है। स्वीकृत उत्तर भयानक था।
कॉनराड लो

मैं ईएस 6 सिंटैक्स का प्रशंसक हूं (पॉलीफ़िल का उपयोग करें, यदि विरासत ब्राउज़र पर समर्थन की आवश्यकता है)। ES7 + ES8 भविष्य होने जा रहे हैं
Fr0zenFyr

जवाबों:


391

शायद आप "मानचित्र" जैसे उच्च-क्रम के कार्यों का उपयोग करना चाहते हैं। मान लें कि आप 'फ़ील्ड' विशेषता द्वारा खोज चाहते हैं:

var elementPos = array.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor);
var objectFound = array[elementPos];

9
इस उत्तर बहुत अच्छा है क्योंकि यह वास्तव में सूचकांक :) प्रदान करके प्रश्न का उत्तर है
counterbeing

3
@ZeroAbsolute आपका लागू किया गया फ़ंक्शन (नक्शा पास किया गया) एक हैश स्ट्रिंग लौटा सकता है जो आपके मानदंडों द्वारा दिए गए प्रत्येक संभावित संयोजन के लिए एक अद्वितीय कुंजी प्रदान करना चाहिए। उदाहरण के लिए function hashf(el) { return String(el.id) + "_" + String(el.name); }:। यह सिर्फ एक संकेत है: elementPos = array.map(hashf(x)).indexOf(hash({id:3, name:'Pablo'}));जाहिर है, मेरे द्वारा प्रदान किया गया हैश फ़ंक्शन '_'आपके मान का हिस्सा बनने के बाद से सभी मामलों के लिए मान्य नहीं है, लेकिन यह सिर्फ एक त्वरित उदाहरण है जिससे आप विभिन्न हैश विधियों का पता लगा सकते हैं।
पाब्लो फ्रांसिस्को पेरेस हिडाल्गो

1
यदि यह नहीं मिला तो यह क्या लौटाएगा? मुझे लगता है -1, बस जिज्ञासु। मैं प्रयोग करूंगा।
नाथन सी। टार्च

1
@ NathanC.Tresch यह -1 लौटाता है क्योंकि यह रिटर्न indexOfवैल्यू है जब यह किसी दिए गए मूल्य का पता नहीं लगा सकता है।
पाब्लो फ्रांसिस्को पेरेस हिडाल्गो

2
हाय सब लोग दो तरीकों का उपयोग करने के बजाय map, indexOfआप केवल एक findIndex....... पूर्व का उपयोग कर सकते हैं :[{id:1},{id:2},{id:3},{id:4}].findIndex(function(obj){return obj.id == 3}) OR [{id:1},{id:2},{id:3},{id:4}].findIndex(obj => obj.id == 3)
उमैर अहमद

64

एरे में एलिमेंट इंडेक्स खोजने का सबसे सरल और आसान तरीका।

ES5 सिंटैक्स: [{id:1},{id:2},{id:3},{id:4}].findIndex(function(obj){return obj.id == 3})

ES6 सिंटैक्स: [{id:1},{id:2},{id:3},{id:4}].findIndex(obj => obj.id == 3)


4
मेरा मानना ​​है कि यह सबसे सुरुचिपूर्ण समाधान है। पीछे की संगतता के बारे में चिंतित लोगों के लिए findIndexआप developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
mrogers

2
मुझे अपने ईएस 6 लिंट टूल में एक चेतावनी मिलती है कि obj.id == 3यहां उपयोग किया जाने वाला ऑपरेटर अप्रत्याशित प्रकार के रूपांतरण का कारण बन सकता है, इसलिए obj.id === 3इसके बजाय ऑपरेटर का उपयोग करें , जो समान मूल्य और प्रकार के लिए परीक्षण करता है।
13

1
यह उत्तर ऊपर दिए गए स्वीकृत उत्तर की तुलना में कम से कम 3.5 गुना तेज है। var elementPos = array.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor);इसका उपयोग करते हुए 0.03500000002532033 मिलीसेकंड [{id:1},{id:2},{id:3},{id:4}].findIndex(obj => obj.id == 3)लिया। इसका उपयोग करते हुए 0.00999999747378752 मिलीसेकंड लिया।
Ovidio Reyna

1
क्योंकि यह पूरे सरणी को पुनरावृत्त नहीं करता है, क्योंकि यह सबसे अधिक प्रभावी है। चयनित उत्तर पूर्ण सरणी को मैप करेगा और फिर findIndex होगा जो एक बार पूरे सरणी के माध्यम से पुनरावृत्त होने के लिए बाध्य है
करुण

26

नया एरे विधि .filter () इसके लिए अच्छा काम करेगा:

var filteredArray = array.filter(function (element) { 
    return element.id === 0;
});

jQuery भी .grep () के साथ ऐसा कर सकता है

संपादित करें: यह ध्यान देने योग्य है कि ये दोनों फ़ंक्शन केवल हुड के तहत पुनरावृत्त होते हैं, उनके बीच एक ध्यान देने योग्य प्रदर्शन अंतर नहीं होगा और अपने स्वयं के फिल्टर फ़ंक्शन को रोल करना होगा, लेकिन पहिया को फिर से क्यों आविष्कार किया जाए।


+1, मैं हमेशा इस तरह की वस्तुओं में निर्मित कार्यों के बारे में भूल जाता हूं।
तीज

59
यह एक सूचकांक वापस नहीं करता है।
एडम ग्रांट

यह इस विशिष्ट प्रश्न का उत्तर नहीं देता है, लेकिन मुझे बहुत मदद करता है! धन्यवाद!
रोजशेड

यह इंडेक्स वापस नहीं करता है।
रिच

10

यदि आप प्रदर्शन के बारे में परवाह करते हैं, तो खोज या फ़िल्टर या मानचित्र या उपरोक्त चर्चा किए गए तरीकों में से किसी के साथ न जाएं

यहाँ सबसे तेज़ विधि का प्रदर्शन करने वाला एक उदाहरण है। यहां वास्तविक परीक्षा की कड़ी है

सेटअप ब्लॉक करें

var items = []

for(var i = 0; i < 1000; i++) {
    items.push({id: i + 1})
}

var find = 523

सबसे तेज़ विधि

var index = -1
for(var i = 0; i < items.length; i++) {
    if(items[i].id === find) {
        index = i;
        break;
    }
}

धीमी विधियाँ

items.findIndex(item => item.id === find)

सबसे कम विधि

items.map(item => item.id).indexOf(find);

2
यह तुलना प्रदान करने के लिए धन्यवाद! क्या सुपर दिलचस्प है कितना प्रदर्शन भिन्न होता है - किस विधि सहित तेज है जो ब्राउज़र / जावास्क्रिप्ट इंजन को चलाने के लिए उपयोग किया जाता है उसके आधार पर भिन्न होता है।
इयान कॉलिन्स

1
मुझे लगता है कि इसे एक उत्तर के रूप में चिह्नित किया जाना चाहिए। यह सबसे तेज़ तरीका और धीमा दिखाता है।
पेनकिलर

आपके बेंचमार्क में, ब्लॉक 2 (findIndex का उपयोग करके) वास्तव में मेरे लिए (Microsoft Edge Chromium 83.0.474.0 पर)
तेज़ है

ब्लॉक 2 अब क्रोम पर भी तेज है
कोडी मिकोल

8
array.forEach(function (elem, i) {  // iterate over all elements of array
    indexes[elem.id] = i;           // take the found id as index for the
});                                 // indexes array and assign i

परिणाम आईडी के लिए एक नज़र सूची है। दिए गए आईडी के साथ हमें रिकॉर्ड का सूचकांक मिलता है।



6

चूंकि नियमित सरणी का उपयोग करने का कोई जवाब नहीं है find:

var one = {id: 1, name: 'one'};
var two = {id: 2, name:'two'}
var arr = [one, two] 

var found = arr.find((a) => a.id === 2)

found === two // true

arr.indexOf(found) // 1


3

const index = array.findIndex(item => item.id === 'your-id');

यह आपको id === your-id के साथ सरणी में आइटम का इंडेक्स मिलना चाहिए

array = [ {id:1}, {id:2} ];

const index = array.findIndex(item => item.id === 2);

console.log(index);


2

मुझे लगता है जैसे आप परीक्षण के लिए एक कॉलबैक के साथ एक साधारण पुनरावृत्ति बना सकते हैं। इस तरह:

function findElements(array, predicate)
{
    var matchingIndices = [];

    for(var j = 0; j < array.length; j++)
    {
        if(predicate(array[j]))
           matchingIndices.push(j);
    }

    return matchingIndices;
}

तब आप ऐसा कर सकते हैं:

var someArray = [
     { id: 1, text: "Hello" },
     { id: 2, text: "World" },
     { id: 3, text: "Sup" },
     { id: 4, text: "Dawg" }
  ];

var matchingIndices = findElements(someArray, function(item)
   {
        return item.id % 2 == 0;
   });

// Should have an array of [1, 3] as the indexes that matched

2

मोंगोबीडी और रोबोमोंगो मैं के लिए तेजस के जवाब को बदलना

matchingIndices.push(j);

सेवा

matchingIndices.push(NumberInt(j+1));

2

ES6 mapफ़ंक्शन का उपयोग करना :

let idToFind = 3;
let index = someArray.map(obj => obj.id).indexOf(idToFind);

2

उपरोक्त सभी महान जवाबों को सारांशित करने के लिए और मेरे उत्तर के अतिरिक्त सभी के बारे में टिप्पणी से कुछ अनुक्रमित पाया।

  1. पहली घटना के सूचकांक को वापस करने के लिए।

const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }];
const idYourAreLookingFor = 2;

//ES5 
//Output: 1
array.map(function (x) { return x.id; }).indexOf(idYourAreLookingFor);

//ES6 
//Output: 1
array.findIndex(obj => obj.id === idYourAreLookingFor);

  1. कम करने का उपयोग करते हुए, सभी घटनाओं के सूचकांक सरणी को वापस करने के लिए।

const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }]
const idYourAreLookingFor = 2;

//ES5
//Output: [1, 4]
array.reduce(function (acc, obj, i) {
  if (obj.id === idYourAreLookingFor)
    acc.push(i);
  return acc;
}, []);

//ES6
//Output: [1, 4]
array.reduce((acc, obj, i) => (obj.id === idYourAreLookingFor) ? acc.concat(i) : acc, [])


0

जैसा कि मैं अभी तक टिप्पणी नहीं कर सकता हूं, मैं उस समाधान को दिखाना चाहता हूं जिसका मैंने उपयोग किया था, जो कि उमैर अहमद द्वारा पोस्ट की गई विधि के आधार पर किया गया था, लेकिन जब आप मूल्य के बजाय एक कुंजी की खोज करना चाहते हैं:

[{"a":true}, {"f":true}, {"g":false}]
.findIndex(function(element){return Object.keys(element)[0] == "g"});

मैं समझता हूं कि यह विस्तारित प्रश्न का उत्तर नहीं देता है, लेकिन शीर्षक निर्दिष्ट नहीं करता है कि प्रत्येक वस्तु से क्या चाहिए था, इसलिए मैं विनम्रतापूर्वक इसे भविष्य में दूसरों को सिरदर्द से बचाने के लिए साझा करना चाहता हूं, जबकि मैं इसे नहीं कर सकता सबसे तेज समाधान।


0

मैंने सुपर-एरे नामक एक छोटी सी उपयोगिता बनाई है, जहां आप ओ (1) जटिलता के साथ एक अद्वितीय पहचानकर्ता द्वारा सरणी में आइटम एक्सेस कर सकते हैं। उदाहरण:

const SuperArray = require('super-array');

const myArray = new SuperArray([
  {id: 'ab1', name: 'John'},
  {id: 'ab2', name: 'Peter'},
]);

console.log(myArray.get('ab1')); // {id: 'ab1', name: 'John'}
console.log(myArray.get('ab2')); // {id: 'ab2', name: 'Peter'}

आप व्यक्तिगत ओपन-सोर्स लाइब्रेरी की पेशकश कैसे करना चाहते हैं? हर जगह यह पोस्ट करने से पहले।
मार्टिन पीटर्स

@MartijnPieters मैंने इसे केवल कुछ प्रासंगिक प्रश्नों के लिए पोस्ट किया है और परियोजना एमआईटी मुक्त है तो सौदा क्या है? शायद आप थोड़ा और सहनशील हो सकते हैं।
पेटोटोमा

0
var test = [
  {id:1, test: 1},
  {id:2, test: 2},
  {id:2, test: 2}
];

var result = test.findIndex(findIndex, '2');

console.log(result);

function findIndex(object) {
  return object.id == this;
}

इंडेक्स 1 लौटाएगा (केवल ES 2016 में काम करता है)


0

मुझे यह तरीका पसंद है क्योंकि ऑब्जेक्ट में किसी भी मूल्य की तुलना करना आसान है, चाहे कितना भी नेस्टेड क्यों न हो।

 while(i<myArray.length && myArray[i].data.value!==value){
  i++; 
}
// i now hows the index value for the match. 
 console.log("Index ->",i );
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.