শর্তের সাথে মিল রেখে অ্যারের ভিতরে অবজেক্টের সূচক পান


320

আমার এইরকম অ্যারে রয়েছে:

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

পুরো অ্যারের উপরে পুনরাবৃত্তি না করে আমি কীভাবে একটি শর্তের সাথে মেলে এমন অবজেক্টের সূচক পেতে পারি?

উদাহরণস্বরূপ, প্রদত্ত prop2=="yutu", আমি সূচক পেতে চাই 1

আমি দেখেছি .indexOf()কিন্তু মনে করি এটি সাধারণ অ্যারেগুলির মতো ব্যবহৃত হয় ["a1","a2",...]। আমি পরীক্ষা করেছিলাম $.grep()তবে এটি সূচি নয়, বস্তুগুলি ফেরত দেয়।

উত্তর:


730

Array.findIndex২০১ of সালের হিসাবে, আপনি এর জন্য (একটি 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);

এটি গুগল ক্রোম, ফায়ারফক্স এবং এজে সমর্থিত। ইন্টারনেট এক্সপ্লোরারের জন্য, লিঙ্কযুক্ত পৃষ্ঠায় একটি পলিফিল রয়েছে।

পারফরম্যান্স নোট

ফাংশন কলগুলি ব্যয়বহুল, অতএব সত্যিকারের বড় অ্যারেগুলির সাথে একটি সাধারণ লুপ এর চেয়ে আরও ভাল সঞ্চালন করবে 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
আমি এখানে একটি অস্থায়ী অ্যারের প্রয়োজন দেখছি না। কেবল পুনরুক্তি ফাংশনটি প্রসঙ্গের উপরে বন্ধ হয়ে যায় এবং একটি ভেরিয়েবল ব্যবহার করুন use এছাড়াও, নন-জিকুয়েরি সংস্করণটি কাজ করে না (ধরুন এটি সূচীতে পাওয়া গেছে 0?) উভয় সমাধান প্রয়োজনের তুলনায় আরও বেশি পুনরাবৃত্তি করে, যা অ্যারে বড় হলে আদর্শের চেয়ে কম (যদিও এর পরিমাণ এত বড় হ'ল মানুষের খেয়াল থাকে কম, যদি না লক্কুল অনেক কিছু ঘটে থাকে )।
টিজে ক্রাউডার

@ থিজি ৪৪৫: এখনও মনে করুন এটি একটি রুবে গোল্ডবার্গ মেশিনের খানিকটা যেখানে একটি সরল লিভারটি কৌশলটি করবে। :-) তবে ওহে, কাজ করে!
টিজে ক্রাউডার

4
আপনি দয়া করে ব্যাখ্যা করতে পারেন কীভাবে x => x.prop2=="yutu"ফাইন্ড ইন্ডেক্স () এর সাথে কাজ করে ?
অভয় পাই

5
@AbhayPai: এটা একই হিসাবেfunction(x) { return x.prop2=="yutu" }
গেয়র্গ

6
আমি পলিফিল ব্যবহার করার পরামর্শটি পছন্দ করি। যাইহোক লিখিত হিসাবে কোড এখনও তীর / ল্যাম্বদা ফাংশন ব্যবহারের কারণে পলিফিল সহ আইই 11 এ ব্যর্থ। index = a.findIndex(function (x) { return x.prop2 == "yutu" })ইস্যুটি ঠিক করা হিসাবে পুনরায় লেখা হয়েছে যাতে পলিফিল কোড সহ, ফাইন্ড ইন্ডেক্স আইই ১১-তে কাজ করেছে
রিক

26

শর্তের সাথে (অ্যারের পাশাপাশি পুনরাবৃত্তি না করে) কীভাবে আমি অবজেক্টের সূচক পেতে পারি?

আপনি পারবেন না, অ্যারে দিয়ে কোনও কিছু পুনরাবৃত্তি করতে হবে (কমপক্ষে একবার)।

যদি শর্তটি অনেক পরিবর্তিত হয়, তবে আপনাকে শর্তগুলির সাথে মেলে কিনা তা দেখতে আপনাকে লুপ করতে হবে এবং এতে থাকা বস্তুগুলি দেখতে হবে। তবে, 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করেনি আমি চেয়েছি ...
রহমান

21

টিজে ক্রাউডার যা বলেছিলেন, সবসময়ই কোনও না কোনও লুকানো পুনরাবৃত্তি থাকবে, যা লোডাশের সাথে এটি হয়ে যায়:

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

1
আপনি সূচকটি পেতে কেবল বিভিন্ন উপায়ে লুপ করতে পারেন, সূচকটি সলিউশন সমাধানের সন্ধান করুন, এমনকি ES6 এ দেশীয় অ্যারে পদ্ধতিতে গৃহীত হয়েছে
কেলি মিলিগান

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;
});

অ্যারের সমস্ত উপাদানগুলির উপরে আইট্রেট করুন। এটি শর্তটি মেলে না তবে সূচকটি দেয় এবং সত্য বা মিথ্যা হয়।

গুরুত্বপূর্ণ হ'ল সত্যের স্পষ্ট প্রত্যাবর্তন মান (বা এমন কোনও মান যা বুলিয়ান ফলাফল সত্য)। 0 (বুলিয়ান (0) === মিথ্যা) সহ একটি সম্ভাব্য সূচকের কারণে একক অ্যাসাইনমেন্ট যথেষ্ট নয়, যা কোনও ত্রুটির কারণ হতে পারে না তবে পুনরাবৃত্তির বিরতি অক্ষম করে।

সম্পাদন করা

উপরের একটি এমনকি সংক্ষিপ্ত সংস্করণ:

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

আপনার দ্বিতীয় স্নিপেটে et চরিত্রটি কী করবে?
সারকান

@ সেকরান, এটি কিছুটা অপারেটর নয়| , এটি সূচক থেকে পাওয়া সংক্ষিপ্ত সংস্করণ (-1 সহ) সত্য - মিথ্যা ফলাফল, যদি কোনও সূচক উপস্থিত থাকে।
নিনা শোলজ

ধন্যবাদ নিনা, ~ চরিত্র ব্যতীত কোড যেমনটি কাজ করে, তাই না?
সারকান 10

@ সরকান, আপনার প্রশ্নটি পরিষ্কার নয় তবে এটি ছাড়া এমনটি হয় না ~
নিনা শোলজ

1
ওহ, !!(index = 0)এবং !!~(index = 0)সত্যই পার্থক্য। ধন্যবাদ!
সারকান 10

4

আপনি নিম্নলিখিত পদ্ধতিতে অ্যারে.প্রোটোটাইপ.সোম () ব্যবহার করতে পারেন (অন্যান্য উত্তরে উল্লিখিত হিসাবে):

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 : শিক্ষার্থীদের জন্য অ্যারে অবজেক্ট তৈরি করুন (yourচ্ছিক আপনি নিজের অ্যারে অবজেক্টটি তৈরি করতে পারেন)।
    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

কেন আপনি ঠিক পুনরাবৃত্তি করতে চান না? নতুন অ্যারে.প্রোটোটাইপ.ফর প্রতিটি এই উদ্দেশ্যে দুর্দান্ত!

আপনি চাইলে একটি পদ্ধতি পদ্ধতি কলের মাধ্যমে বাইনারি অনুসন্ধান গাছ ব্যবহার করতে পারেন। এটি জেএসের বিটি এবং লাল কালো অনুসন্ধান গাছের ঝরঝরে বাস্তবায়ন - https://github.com/vadimg/js_bintree - তবে আপনি একই সময়ে সূচকটি খুঁজে পেতে পারবেন কিনা তা আমি নিশ্চিত নই।


1

অ্যারে.রেডস () ব্যবহার করে এক ধাপ - কোনও জিকুয়েরি নেই

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 এর অ্যারে.ফাইন্ড ইন্ডেক্স উল্লেখ করেছে। এবং আরও কিছু উত্তর হ'ল অ্যারে.সোম পদ্ধতিটি ব্যবহার করে ES5 এর জন্য কার্যকর।

আরও একটি মার্জিত পদ্ধতির হতে পারে

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

একই সাথে আমি জোর দিতে চাই, অ্যারে.সোম বাইনারি বা অন্যান্য দক্ষ অনুসন্ধান কৌশল দ্বারা প্রয়োগ করা যেতে পারে। সুতরাং, এটি কিছু ব্রাউজারে লুপের জন্য আরও ভাল সম্পাদন করতে পারে।


0

এই কোড ব্যবহার করে দেখুন

var x = [{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"}]
let index = x.findIndex(x => x.prop1 === 'zxvz')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.