जावास्क्रिप्ट में अपनी संपत्ति द्वारा वस्तु का सूचकांक कैसे प्राप्त करें?


241

उदाहरण के लिए, मेरे पास:

var Data = [
  { id_list: 1, name: 'Nick', token: '312312' },
  { id_list: 2, name: 'John', token: '123123' },
]

फिर, मैं उदाहरण के लिए, इस ऑब्जेक्ट को क्रमबद्ध / रिवर्स करना चाहता हूं name। और फिर मैं कुछ इस तरह प्राप्त करना चाहता हूं:

var Data = [
  { id_list: 2, name: 'John', token: '123123' },
  { id_list: 1, name: 'Nick', token: '312312' },
]

और अब मैं संपत्ति name='John'के मूल्य को प्राप्त करने के लिए संपत्ति के साथ वस्तु के सूचकांक को जानना चाहता हूं ।

मैं समस्या को कैसे हल करूं?


संपत्ति की खोज करने से पहले आप सूची को क्यों क्रमबद्ध करना चाहते हैं?
जेजे

जावास्क्रिप्ट ऑब्जेक्ट हैं {Key:Value}, मैंने इसे आपके लिए तय किया है।
रॉकेट हज़मत


यदि आप उत्तरों के माध्यम से स्कैन करते हैं, तो ऐसा प्रतीत होता है कि कुछ मूल Dataवस्तु है। यह केवल एक पूंजीगत परिवर्तनशील नाम है, जो सम्मेलन के खिलाफ है। अगर कोई और इससे परेशान होता है, तो मैं इस नामकरण को ठीक करने के लिए सवाल और जवाब का संपादन करूंगा।
रॉय

जवाबों:


170

जैसा कि अन्य उत्तर बताते हैं, सरणी के माध्यम से लूपिंग शायद सबसे अच्छा तरीका है। लेकिन मैं इसे स्वयं के कार्य में लगाऊंगा, और इसे थोड़ा और सार बनाऊंगा:

function findWithAttr(array, attr, value) {
    for(var i = 0; i < array.length; i += 1) {
        if(array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

var Data = [
    {id_list: 2, name: 'John', token: '123123'},
    {id_list: 1, name: 'Nick', token: '312312'}
];

इसके साथ, न केवल आप पा सकते हैं कि किस में 'जॉन' है, बल्कि आप पा सकते हैं जिसमें टोकन '312312' शामिल है:

findWithAttr(Data, 'name', 'John'); // returns 0
findWithAttr(Data, 'token', '312312'); // returns 1
findWithAttr(Data, 'id_list', '10'); // returns -1

संपादित करें: अद्यतित फ़ंक्शन -1 जब नहीं मिला तो यह Array.prototype.indexOf () के समान निर्माण का अनुसरण करता है


1
एक विशेषता स्तर से अधिक गहरी खोज को कवर करने के लिए इसका उत्तर देने के लिए जोड़ा गया उत्तर। इस क्रिस के लिए धन्यवाद - वास्तव में मदद की: D
एड शी

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

यह मत करो। उच्च-क्रम के कार्यों का उपयोग करना सीखें यह काम करने का पुराना तरीका है।
नेतृत्व किया

327

चूंकि सॉर्ट भाग पहले ही उत्तर दिया गया है। मैं आपके सरणी में किसी गुण का अनुक्रमणिका प्राप्त करने के लिए बस एक और सुंदर तरीका प्रस्तावित करने जा रहा हूं

आपका उदाहरण है:

var Data = [
    {id_list:1, name:'Nick',token:'312312'},
    {id_list:2,name:'John',token:'123123'}
]

तुम कर सकते हो:

var index = Data.map(function(e) { return e.name; }).indexOf('Nick');

Array.prototype.mapIE7 या IE8 पर उपलब्ध नहीं है। ES5 संगतता

और यहाँ यह ES6 और एरो सिंटैक्स के साथ है, जो और भी सरल है:

const index = Data.map(e => e.name).indexOf('Nick');

4
मुझे पूरी सरणी को पुनरावृत्त करना है, चाहे जो भी हो। पहली विधि की जरूरत नहीं है।
जर्मन एटानासियो

1
सरल, लेकिन बड़े डेटासेट का उपयोग करते समय प्रदर्शन को ध्यान में
रखें

1
वास्तव में महान जवाब ने मुझे इस समस्या के साथ मदद की!
NiallMitch14

1
यह उपाय प्यारा है। क्या आप एक हज़ार साल पुराने हो सकते हैं, सर।
दीपावली

3
एक मानचित्र और फिर ES6 संस्करण में indexOf करने का मतलब है कि वे दो बार सरणी पर लूपिंग करेंगे। इसके बजाय आप findIndex विधि मेरा उत्तर में दिखाया गया है का उपयोग करना चाहिए
silverlight513

209

यदि आप ES6 का उपयोग करके ठीक हैं। Arrays में अब findIndex function है। जिसका मतलब है कि आप कुछ इस तरह से कर सकते हैं:

const index = Data.findIndex(item => item.name === 'John');

6
सबसे प्रत्यक्ष और सुरुचिपूर्ण समाधान के लिए हाथ नीचे, मैं एक छोटा सा नहीं बनाता हूं कि findIndex लालची है - मेरे मामले में यह एकदम सही था - लेकिन उपयोगकर्ताओं को पता है कि अगर आपके पास डुप्लिकेट मान वाले ऑब्जेक्ट हैं (यानी दो ऑब्जेक्ट्स के साथ name: John) तो यह केवल वापस आ जाएगा पहला मैच
२१:२१ पर ग्रेडफ़ॉक्स

बहुत बढ़िया!! धन्यवाद।
Moreirapontocom

@GrayedFox क्या आपको लालच नहीं था? लालची का अर्थ है अधिक परिणाम और findIndex केवल पहला मैच लौटाता है।
जोस

1
क्षमा करें @Jos, लेकिन मुझे लगता है कि आप काफी नहीं समझते कि एक लालची खोज एल्गोरिथ्म क्या करता है । एक लालची एल्गोरिथ्म केवल उस जानकारी को मानता है जिसके पास हाथ है, जो कम्प्यूटेशनल रूप से कुशल है, कहते हैं, किसी सूची में एक आइटम की खोज करना जब आपको केवल एक परिणाम की आवश्यकता होती है। FindIndex विधि लालची है क्योंकि यह केवल पहला मैच ही लौटाती है। अगर यह लालच नहीं था तो यह खोज जारी रहेगी। आप "लालची" शब्द के बारे में सोच रहे हैं क्योंकि यह दिन-प्रतिदिन की अंग्रेजी में उपयोग किया जाता है, लेकिन प्रोग्रामिंग (यानी SO) के संदर्भ में, यह आपके विचार के विपरीत है;)
ग्रेडफ़ॉक्स

@GrayedFox समझाने के लिए धन्यवाद। लालची के लिए मेरा संदर्भ वास्तव में प्रोग्रामिंग से था, लेकिन नियमित अभिव्यक्ति से संबंधित था, जहां लालची गैर-लालची से अधिक चरित्र लेता है! :-)
जोस

28
var index = Data.findIndex(item => item.name == "John")

जिसका एक सरलीकृत संस्करण है:

var index = Data.findIndex(function(item){ return item.name == "John"})

से mozilla.org:

FindIndex () विधि सरणी में पहले तत्व के सूचकांक को लौटाता है जो प्रदान किए गए परीक्षण फ़ंक्शन को संतुष्ट करता है। अन्यथा -1 वापस कर दिया जाता है।


2
स्ट्रिंग = तुलना के लिए "===" का उपयोग करें यह इस उत्तर में केवल एक चीज गायब है।
ब्रूनो तवरेज

@BrunoTavares, आपको लगता है कि इस मामले में कौन सा परिदृश्य अलग होगा?
edank

1
@edank यदि ओपी को tokenक्षेत्र के बजाय क्षेत्र की जांच करनी थी, तो nameसमस्या हो सकती है, जैसा कि Data[0].token == 312312मूल्यांकन करता है true, लेकिन Data[0].token === 321321मूल्यांकन करता है false
केम

@edank इस उत्तर में एक नज़र डालें। stackoverflow.com/questions/359494/…
ब्रूनो

23

यदि आपके पास IE के साथ समस्याएँ हैं, तो आप मैप का उपयोग कर सकते हैं () फ़ंक्शन जो 9.0 से समर्थित है:

var index = Data.map(item => item.name).indexOf("Nick");

1
नीचे दिया गया उत्तर अधिक जानकारी प्रदान करता है और पहले पोस्ट किया गया था।
अलेक्जेंडर

यह निश्चित रूप से इसके लिए सबसे अच्छा समाधान है।
19 को

4

मेरे लिए एकमात्र तरीका सभी प्रकार से लूपिंग करना है:

var index=-1;
for(var i=0;i<Data.length;i++)
  if(Data[i].name==="John"){index=i;break;}

या असंवेदनशील मामला:

var index=-1;
for(var i=0;i<Data.length;i++)
  if(Data[i].name.toLowerCase()==="john"){index=i;break;}

परिणामी चर अनुक्रमणिका में ऑब्जेक्ट का इंडेक्स होता है या नहीं मिलने पर -1।


2

एक प्रोटोटाइप तरीका है

(function(){
  if (!Array.prototype.indexOfPropertyValue){
    Array.prototype.indexOfPropertyValue = function(prop,value){
      for (var index = 0; index < this.length; index++){
        if (this[index][prop]){
          if (this[index][prop] == value){
            return index;
          }
        }
      }
      return -1;
    }
  }
 })();
 // usage:
 var Data = [
 {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}];
 Data.indexOfPropertyValue('name','John'); // returns 1 (index of array);
 Data.indexOfPropertyValue('name','Invalid name') // returns -1 (no result);
 var indexOfArray = Data.indexOfPropertyValue('name','John');
 Data[indexOfArray] // returns desired object.

मुझे अपनी स्थिति के लिए काम करने के लिए इसे थोड़ा बदलना पड़ा - मैं शून्य के मान के साथ एक संपत्ति के सूचकांक की तलाश कर रहा था और पांचवीं पंक्ति इस कारण उस सूचकांक को छोड़ रही थी।
डेविड ब्रूनो

1

आप अपने छँटाई mecanism को परिभाषित करने के लिए पैरामीटर के रूप में एक कस्टम फ़ंक्शन का उपयोग करके Array.sort का उपयोग कर सकते हैं।

आपके उदाहरण में, यह देगा:

var Data = [
    {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}
]

Data.sort(function(a, b){
    return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
});

alert("First name is : " + Data[0].name); // alerts 'John'
alert("Second name is : " + Data[1].name); // alerts 'Nick'

सॉर्ट फ़ंक्शन को या तो -1 वापस आना चाहिए, अगर बी से पहले आना चाहिए, 1 अगर बी और 0 के बाद आना चाहिए तो दोनों समान हैं। यह सरणी को क्रमबद्ध करने के लिए आपके सॉर्टिंग फ़ंक्शन में सही तर्क को परिभाषित करना है।

संपादित करें: अपने प्रश्न के अंतिम भाग को याद किया जहां आप सूचकांक जानना चाहते हैं। आपको यह जानने के लिए सरणी के माध्यम से लूप करना होगा कि दूसरों ने कहा है।


1

बस अपने सरणी के माध्यम से जाओ और स्थिति का पता लगाएं:

var i = 0;
for(var item in Data) {
    if(Data[item].name == 'John')
        break;
    i++;
}
alert(i);

यह होना चाहिए if(Data[item].name == 'John'), मैंने इसे आपके लिए तय किया।
रॉकेट हज़मत

यह एक पल है। यदि चर 'नहीं मिला' मैं सकारात्मक सूचकांक होते हैं। और परीक्षण करने के लिए 'नहीं मिला' की तुलना करने की जरूरत है अगर मैं === Data.length
एंड्रयू डी।

दूसरा क्षण यह है कि सरणी में गैर-सूचक कस्टम गुण हैं। उदाहरण के लिए: var डेटा [1,2,3,4,5]; डाटा [ "परीक्षण"] 7897 =; आउटपुट की तुलना करें: के लिए (डेटा में var i) चेतावनी (डेटा [i]); और (var i = 0; i <Data.length; i ++) अलर्ट (डेटा [i]);
एंड्रयू डी।


1

आप एक छोटे से काम का उपयोग क्यों नहीं करते हैं?

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

var Data = [
    {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}
    ]
var searchArr = []
Data.forEach(function(one){
  searchArr[one.name]=one;
})
console.log(searchArr['Nick'])

http://jsbin.com/xibala/1/edit

जीवंत उदाहरण।


इसका मतलब है कि हर चीज को पहले टटोलना ... तब वस्तुओं को संशोधित करना (जब तक कि आप उन्हें क्लोन नहीं करते लेकिन यह और भी अधिक उपरि है)। और उसके बाद आप फिर से लूप करते हैं (आंशिक रूप से कम से कम)।
जोस

1

विस्तारित क्रिस पिकेट का उत्तर क्योंकि मेरे मामले में मुझे एक विशेषता स्तर से अधिक गहरी खोज करने की आवश्यकता थी:

function findWithAttr(array, attr, value) {
  if (attr.indexOf('.') >= 0) {
    var split = attr.split('.');
    var attr1 = split[0];
    var attr2 = split[1];
    for(var i = 0; i < array.length; i += 1) {
      if(array[i][attr1][attr2] === value) {
        return i;
      }
    }
  } else {
    for(var i = 0; i < array.length; i += 1) {
      if(array[i][attr] === value) {
        return i;
      }
    }
  };
};

आप फ़ंक्शन में 'attr1.attr2' पास कर सकते हैं


1

इस बारे में क्या ? :

Data.indexOf(_.find(Data, function(element) {
  return element.name === 'John';
}));

मान लें कि आप लॉश या अंडरस्कोरज का उपयोग कर रहे हैं।


1
var fields = {
teste:
{
    Acess:
    {
        Edit: true,
      View: false

      }
 },
teste1:
{
    Acess:
    {
        Edit: false,
      View: false

      }
  }
};

console.log(find(fields,'teste'));
function find(fields,field){
    for(key in fields){
        if(key == field){
        return true;
    }
}
return false;
}

यदि आपके पास अंदर की वस्तुओं के साथ एक वस्तु है, यदि आप जानते हैं कि क्या कोई वस्तु मास्टर ऑब्जेक्ट पर शामिल है, तो बस लगाएं (MasterObject, 'ऑब्जेक्ट टू सर्च'), यह फ़ंक्शन मौजूद है या नहीं तो प्रतिक्रिया वापस कर देगा (TRUE या FALSE) ), मुझे उम्मीद है कि इस के साथ मदद, JSFiddle पर छूट देख सकते हैं ।


जवाब के साथ कुछ स्पष्टीकरण जोड़ें कि यह उत्तर ओपी को वर्तमान मुद्दे को ठीक करने में कैसे मदद करता है
ρяєρ withя K

@ ρя suggestionρєяK, आपके सुझाव के लिए धन्यवाद, मैं पहले से ही स्पष्टीकरण जोड़ रहा हूं :)
पेड्रो

1
let indexOf = -1;
let theProperty = "value"
let searchFor = "something";

theArray.every(function (element, index) {

    if (element[theProperty] === searchFor) {
        indexOf = index;
        return false;
    }
    return true;
});

1
collection.findIndex(item => item.value === 'smth') !== -1

हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है। कृपया व्याख्यात्मक टिप्पणियों के साथ अपने कोड को भीड़ने की कोशिश न करें, क्योंकि इससे कोड और स्पष्टीकरण दोनों की पठनीयता कम हो जाती है!
गुडबाय StackExchange

1

अगर आप प्रॉपर्टी की वैल्यू टोकन के लिए लेना चाहते हैं तो आप यह भी ट्राई कर सकते हैं

    let data=[
      { id_list: 1, name: 'Nick', token: '312312' },
      { id_list: 2, name: 'John', token: '123123' },
    ]

    let resultingToken =  data[_.findKey(data,['name','John'])].token

जहाँ _.findKey एक लॉश का कार्य है


0

वैकल्पिक रूप से जर्मन अटानासियो रुइज़ के उत्तर के लिए, आप Array.reduce () के बजाय Array.reduce () का उपयोग करके 2 लूप को समाप्त कर सकते हैं;

var Data = [
    { name: 'hypno7oad' }
]
var indexOfTarget = Data.reduce(function (indexOfTarget, element, currentIndex) {
    return (element.name === 'hypno7oad') ? currentIndex : indexOfTarget;
}, -1);

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