कैसे सरणी में तत्व की सभी घटनाओं के सूचकांक को खोजने के लिए?


108

मैं एक तत्व के सभी उदाहरणों के सूचकांक को खोजने की कोशिश कर रहा हूं, कहते हैं, "नैनो", एक जावास्क्रिप्ट सरणी में।

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

मैंने jQuery.inArray , या इसी तरह, .indexOf () की कोशिश की , लेकिन इसने केवल इस मामले में तत्व के अंतिम उदाहरण, यानी 5 का सूचकांक दिया।

मैं इसे सभी उदाहरणों के लिए कैसे प्राप्त करूं?

जवाबों:


115

.indexOf()विधि कि निर्दिष्ट सूचकांक से खोज शुरू करने के लिए है, तो आप एक पाश में यह कॉल कर सकते हैं एक विशेष मूल्य के सभी उदाहरणों को खोजने के लिए एक वैकल्पिक दूसरा पैरामीटर है:

function getAllIndexes(arr, val) {
    var indexes = [], i = -1;
    while ((i = arr.indexOf(val, i+1)) != -1){
        indexes.push(i);
    }
    return indexes;
}

var indexes = getAllIndexes(Cars, "Nano");

आप वास्तव में यह स्पष्ट नहीं करते हैं कि आप अनुक्रमित का उपयोग कैसे करना चाहते हैं, इसलिए मेरा फ़ंक्शन उन्हें एक सरणी के रूप में लौटाता है (या यदि मूल्य नहीं मिला है तो एक खाली सरणी देता है), लेकिन आप व्यक्तिगत सूचकांक मूल्यों के साथ कुछ और कर सकते हैं लूप के अंदर।

अद्यतन: VisioN की टिप्पणी के अनुसार, लूप के लिए एक सरल समान कार्य को अधिक कुशलता से किया जाएगा, और इसे समझना आसान है और इसलिए इसे बनाए रखना आसान है:

function getAllIndexes(arr, val) {
    var indexes = [], i;
    for(i = 0; i < arr.length; i++)
        if (arr[i] === val)
            indexes.push(i);
    return indexes;
}

1
यह forइंडेक्स सरणी पॉप्युलेटिंग के साथ एक लूप के लिए तेज विकल्प प्रतीत नहीं होता है ।
विजीएनएन

1
@VisioN - हां, ऐरे के ऊपर लूप के लिए एक सादा भी सरल होगा, लेकिन जब से ओपी ने उपयोग करने की कोशिश का उल्लेख किया है, .indexOf()मैं यह दिखाना चाहता था कि यह काम कर सकता है। (मुझे लगता है कि मुझे पता चला कि ओपी यह पता लगा सकता है कि यह लूप के साथ कैसे किया जा सकता है।) बेशक वहाँ इसे करने के अन्य तरीके हैं, उदाहरण के लिए,Cars.reduce(function(a, v, i) { if (v==="Nano") a.push(i); return a; }, []);
nnnnnn 10

मैं बता सकता हूं कि आप उत्तरी अमेरिका से हैं क्योंकि आपने indexesइसके बजाय इस्तेमाल किया था indices: P
4castle

2
@ 4castle - हा। नहीं, मैं नहीं हूँ। "इंडिसेस" और "इंडेक्स" दोनों सही हैं, और मैं दोनों के बीच बारी-बारी से काम करता हूं। मैंने क्षेत्रीय बोली के रूप में कभी ऐसा नहीं सोचा था। दिलचस्प।
nnnnnn

ध्यान दें कि दिया गया पहला उदाहरण स्ट्रिंग्स और सरणियों के लिए बढ़िया काम करता है। दूसरा केवल सरणियों के लिए काम करता है।
सेथव्हाईट

80

एक अन्य वैकल्पिक समाधान का उपयोग करना है Array.prototype.reduce():

["Nano","Volvo","BMW","Nano","VW","Nano"].reduce(function(a, e, i) {
    if (e === 'Nano')
        a.push(i);
    return a;
}, []);   // [0, 3, 5]

NB: विधि के लिए ब्राउज़र संगतता की जाँच करें reduceऔर यदि आवश्यक हो तो पॉलीफ़िल का उपयोग करें ।


2
+1। मजेदार संयोग: मैंने बस इस समाधान का सुझाव देने के लिए अपने जवाब के तहत अपनी टिप्पणी के लिए अपना जवाब संपादित किया, फिर मैं ताज़ा करता हूं और देखता हूं कि आपने एक ही चीज को केवल एक चर नाम के साथ कोडित किया है।
nnnnnn

@nnnnnn :)हाँ, मुझे लगा कि शायद reduceएक अच्छा विकल्प हो सकता है।
VisioN

26
array.reduce((a, e, i) => (e === value) ? a.concat(i) : a, [])
यार्कर्ट

मैं गूगलेड contatकी तुलना में धीमा pushहूं, इसलिए मैं जवाब के साथ रहता हूं।
आंद्रे एलरिको

54

Array.prototyp.map () और Array.prototyp.filter () का उपयोग कर एक और तरीका :

var indices = array.map((e, i) => e === value ? i : '').filter(String)

3
महान, यह काम करता है। क्या आप बता सकते हैं कि फिल्टर (स्ट्रिंग) की भूमिका क्या है
मुथमीज़चेलवन। V

2
@Muthu map(…)की समानता के लिए प्रत्येक यात्रा पर जाँच करता है eऔर value। जब वे मिलान करते हैं तो सूचकांक वापस आ जाता है, अन्यथा एक खाली स्ट्रिंग। उन मिथ्या मूल्यों से छुटकारा पाने के लिए, filter(String)सुनिश्चित करें कि परिणाम में केवल वे मान शामिल हैं जो स्ट्रिंग के प्रकार और रिक्त नहीं हैं। filter(String)के रूप में भी लिखा जा सकता है:filter(e => e !== '')
yckart

3
... या: String(thing)एक स्ट्रिंग के लिए कुछ भी coerces। Array#filterउन सभी मूल्यों की एक सरणी देता है जिनके लिए स्थिति सत्य है । क्योंकि खाली तार मिथ्या हैं , इसलिए उन्हें सरणी में शामिल नहीं किया गया है।
यार्क

आपकी व्याख्या के लिए धन्यवाद, यह वास्तव में मेरे लिए मददगार है
मुत्मीज़चेलवन। V

2
अगर मैं इसे किसी प्रोजेक्ट में देखता हूं तो मुझे भ्रम होगा। यह "फ़िल्टर टू स्ट्रिंग्स" की तरह पढ़ता है, जिसका अर्थ केवल यह है कि अगर यह एक तार है। और फिर परिणामी सरणी संख्याओं के रूप में अनुक्रमणिका होगी, संख्या नहीं।
माइकल पियर्सन

14

Es6 शैली के साथ और अधिक सरल तरीका।

const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);


//Examples:
var cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
indexOfAll(cars, "Nano"); //[0, 3, 5]
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []

12

आप दोनों का उपयोग करके इसका एक सरल पठनीय समाधान लिख सकते हैं mapऔर filter:

const nanoIndexes = Cars
  .map((car, i) => car === 'Nano' ? i : -1)
  .filter(index => index !== -1);

संपादित करें: यदि आपको IE / Edge का समर्थन करने की आवश्यकता नहीं है (या अपना कोड ट्रांसप्लान कर रहे हैं), ES2019 ने हमें फ्लैटपाइप दिया , जो आपको एक साधारण लाइनर में ऐसा करने देता है:

const nanoIndexes = Cars.flatMap((car, i) => car === 'Nano' ? i : []);

6

नोट: MDN एक लूप का उपयोग करके एक विधि देता है :

var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
  indices.push(idx);
  idx = array.indexOf(element, idx + 1);
}

मैं यह नहीं कहूंगा कि यह अन्य उत्तरों से बेहतर है। सिर्फ दिलचस्प।


4

मैं बस एक और आसान विधि के साथ अपडेट करना चाहता हूं।

आप फॉरच विधि का भी उपयोग कर सकते हैं।

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

var result = [];

Cars.forEach((car, index) => car === 'Nano' ? result.push(index) : null)

3
const indexes = cars
    .map((car, i) => car === "Nano" ? i : null)
    .filter(i => i !== null)

1
इंडेक्स शून्य-आधारित हैं, इसलिए यह विफल हो जाएगा यदि पहली कार नैनो है।
ज़ैक डेल्वेंथल

1
ओह देखो, तुम्हारे पास एक समाधान है और मेरा जैसा दिखता है। मुझे लिखने में समय बिताने से पहले मुझे आपका देखना चाहिए था। लूप्स के लिए बस इतने सारे फैलाव थे मैंने सोचा, "मैं 2 सेकंड में अपना जवाब दे सकता हूं।"
माइकल पियर्सन

हाँ। ये ज़्यादातर जटिल हैं। अच्छा सुधार।
ज़ैक डेल्वेंथल

2

यह मेरे लिए काम किया:

let array1 = [5, 12, 8, 130, 44, 12, 45, 12, 56];
let numToFind = 12
let indexesOf12 = [] // the number whose occurrence in the array we want to find

array1.forEach(function(elem, index, array) {
    if (elem === numToFind) {indexesOf12.push(index)}
    return indexesOf12
})

console.log(indexesOf12) // outputs [1, 5, 7]

1

बस दूसरी विधि साझा करने के लिए, आप परिणाम प्राप्त करने के लिए फंक्शन जेनरेटर का उपयोग कर सकते हैं :

function findAllIndexOf(target, needle) {
  return [].concat(...(function*(){
    for (var i = 0; i < target.length; i++) if (target[i] === needle) yield [i];
  })());
}

var target = "hellooooo";
var target2 = ['w','o',1,3,'l','o'];

console.log(findAllIndexOf(target, 'o'));
console.log(findAllIndexOf(target2, 'o'));


0

हम स्टैक में "i" का उपयोग कर सकते हैं और हर बार जब हम स्थिति को पकड़ते हैं तो "अरे [i] == मान"

इसे देखो:

static void getindex(int arr[], int value)
{
    Stack<Integer>st= new Stack<Integer>();
    int n= arr.length;
    for(int i=n-1; i>=0 ;i--)
    {
        if(arr[i]==value)
        {
            st.push(i);
        }
    }   
    while(!st.isEmpty())
    {
        System.out.println(st.peek()+" ");
        st.pop(); 
    }
}

2
प्रश्न का टैग लगा है javascript, जबकि आपका उत्तर Javaमुझे विश्वास है?
noggin182

0
["a", "b", "a", "b"]
   .map((val, index) => ({ val, index }))
   .filter(({val, index}) => val === "a")
   .map(({val, index}) => index)

=> [0, 2]

कृपया कोड के लिए एक आवश्यक स्पष्टीकरण या इनलाइन टिप्पणी लिखें। BTW, आपके समाधान ने काम किया लेकिन इसमें 3 पुनरावृत्तियों शामिल हैं ...
JustWe

0

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

if (!Array.prototype.filterIndex) {
Array.prototype.filterIndex = function (func, thisArg) {

    'use strict';
    if (!((typeof func === 'Function' || typeof func === 'function') && this))
        throw new TypeError();

    let len = this.length >>> 0,
        res = new Array(len), // preallocate array
        t = this, c = 0, i = -1;

    let kValue;
    if (thisArg === undefined) {
        while (++i !== len) {
            // checks to see if the key was set
            if (i in this) {
                kValue = t[i]; // in case t is changed in callback
                if (func(t[i], i, t)) {
                    res[c++] = i;
                }
            }
        }
    }
    else {
        while (++i !== len) {
            // checks to see if the key was set
            if (i in this) {
                kValue = t[i];
                if (func.call(thisArg, t[i], i, t)) {
                    res[c++] = i;
                }
            }
        }
    }

    res.length = c; // shrink down array to proper size
    return res;
};

}

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

[2,23,1,2,3,4,52,2].filterIndex(element => element === 2)

result: [0, 3, 7]

-1

findIndexकेवल पहला इंडेक्स प्राप्त करता है जो कॉलबैक आउटपुट से मेल खाता है। आप findIndexesऐरे को बढ़ाकर अपने खुद को लागू कर सकते हैं , फिर अपने सरणियों को नई संरचना में डाल सकते हैं।

class EnhancedArray extends Array {
  findIndexes(where) {
    return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []);
  }
}
   /*----Working with simple data structure (array of numbers) ---*/

//existing array
let myArray = [1, 3, 5, 5, 4, 5];

//cast it :
myArray = new EnhancedArray(...myArray);

//run
console.log(
   myArray.findIndexes((e) => e===5)
)
/*----Working with Array of complex items structure-*/

let arr = [{name: 'Ahmed'}, {name: 'Rami'}, {name: 'Abdennour'}];

arr= new EnhancedArray(...arr);


console.log(
  arr.findIndexes((o) => o.name.startsWith('A'))
)


-1

यदि आप अंडरस्कोर / लॉश का उपयोग करने का इरादा रखते हैं, तो आप कर सकते हैं

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

_.chain(Cars).map((v, i)=> [i, v === "Nano"]).filter(v=>v[1]).map(v=>v[0]).value()

[0, 3, 5]

2
इसके लिए आपको वास्तव में किसी पुस्तकालय की आवश्यकता नहीं है:(["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"]).map((v, i)=> [i, v === "Nano"]).filter(v=>v[1]).map(v=>v[0])
edjroot
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.