javascript - objects - js object




البحث عن عنصر بالمعرف في صفيف من كائنات JavaScript (19)

لدي صفيف:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]

أنا غير قادر على تغيير بنية الصفيف. يتم تمرير معرف 45 ، وأريد الحصول على 'bar' لهذا الكائن في الصفيف.

كيف أفعل ذلك في JavaScript أو باستخدام jQuery؟


باستخدام الأصلي Array.reduce

var array = [ {'id':'73' ,'foo':'bar'} , {'id':'45' ,'foo':'bar'} , ];
var id = 73;
var found = array.reduce(function(a, b){
    return (a.id==id && a) || (b.id == id && b)
});

إرجاع عنصر الكائن إذا تم العثور عليه ، وإلا false


أعتقد أن أسهل طريقة هي التالية ، ولكنها لن تعمل على Internet Explorer 8 (أو إصدار سابق):

var result = myArray.filter(function(v) {
    return v.id === '45'; // Filter out the appropriate one
})[0].foo; // Get result and access the foo property

أنا حقا أحب الإجابة التي قدمها آرون ديغولا ولكن احتاجت للحفاظ على مجموعة من الأشياء حتى أتمكن من التكرار من خلال ذلك في وقت لاحق. لذلك أنا تعديله ل

	var indexer = {};
	for (var i = 0; i < array.length; i++) {
	    indexer[array[i].id] = parseInt(i);
	}
	
	//Then you can access object properties in your array using 
	array[indexer[id]].property


إذا قمت بذلك عدة مرات ، فيمكنك إعداد خريطة (ES6):

var map = new Map(myArray.map(el=>[el.id,el]));

ثم يمكنك ببساطة القيام بما يلي:

map.get(27).foo

استخدم Array.prototype.filter() .

عرض توضيحي : https://jsfiddle.net/sumitridhal/r0cz0w5o/4/

JSON

var jsonObj =[
 {
  "name": "Me",
  "info": {
   "age": "15",
   "favColor": "Green",
   "pets": true
  }
 },
 {
  "name": "Alex",
  "info": {
   "age": "16",
   "favColor": "orange",
   "pets": false
  }
 },
{
  "name": "Kyle",
  "info": {
   "age": "15",
   "favColor": "Blue",
   "pets": false
  }
 }
];

منقي

var getPerson = function(name){
    return jsonObj.filter(function(obj) {
      return obj.name === name;
    });
}

استخدم طريقة مرشح jQuery:

 $(myArray).filter(function()
 {
     return this.id == desiredId;
 }).first();

سيعود هذا العنصر الأول بالمعرف المحدد.

كما أن لديها ميزة لطيفة شكل C # LINQ أبحث.


بالرغم من وجود العديد من الإجابات الصحيحة هنا ، إلا أن الكثير منها لا يعالج حقيقة أن هذه العملية مكلفة للغاية إذا تمت أكثر من مرة. في الحالة القصوى يمكن أن يكون هذا سبب مشاكل الأداء الحقيقي.

في العالم الحقيقي ، إذا كنت تقوم بمعالجة الكثير من العناصر والأداء هو مصدر قلق ، فمن الأسرع بكثير إنشاء بحث:

var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];

var lookup = items.reduce((o,i)=>o[i.id]=o,{});

يمكنك الحصول على العناصر في وقت ثابت مثل:

var bar = o[id];

قد تفكر أيضًا في استخدام خريطة بدلاً من كائن مثل البحث: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map


بدءاً من إجابة aggaton ، هذه هي الدالة التي تقوم فعليًا بإرجاع العنصر المطلوب (أو null إذا لم يتم العثور عليه) ، نظرًا array ووظيفة callback التي تعرض قيمة صوابية للعنصر "الصحيح":

function findElement(array, callback) {
    var elem;
    return array.some(function(e) {
        if (callback(e)) {
            elem = e;
            return true;
        }
    }) ? elem : null;
});

فقط تذكر أن هذا لا يعمل أصلاً على IE8- ، لأنه لا يدعم some . يمكن توفير polyfill ، بدلاً من ذلك ، هناك دائمًا حلقة كلاسيكية للحلقة:

function findElement(array, callback) {
    for (var i = 0; i < array.length; i++)
        if (callback(array[i])) return array[i];
    return null;
});

انها في الواقع أسرع وأكثر إحكاما. ولكن إذا كنت لا ترغب في إعادة اختراع العجلة ، أقترح استخدام مكتبة أدوات مساعدة مثل تسطير سفلي أو تسريحة.


حاول القيام بما يلي

function findById(source, id) {
  for (var i = 0; i < source.length; i++) {
    if (source[i].id === id) {
      return source[i];
    }
  }
  throw "Couldn't find object with id: " + id;
}

حل آخر هو إنشاء كائن بحث:

var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
    lookup[array[i].id] = array[i];
}

... now you can use lookup[id]...

هذا مثير للاهتمام بشكل خاص إذا كنت بحاجة إلى القيام بالعديد من عمليات البحث.

لن يحتاج ذلك إلى المزيد من الذاكرة نظرًا لأنه سيتم مشاركة المعرفات والكائنات.


طالما أن المستعرض يدعم ECMA-262 ، الإصدار الخامس (ديسمبر 2009) ، يجب أن يعمل هذا ، على سبيل المثال:

var bFound = myArray.some(function (obj) {
    return obj.id === 45;
});

قد يفيد هذا الحل أيضًا:

Array.prototype.grep = function (key, value) {
    var that = this, ret = [];
    this.forEach(function (elem, index) {
        if (elem[key] === value) {
            ret.push(that[index]);
        }
    });
    return ret.length < 2 ? ret[0] : ret;
};
var bar = myArray.grep("id","45");

أنا جعلت ذلك تماما مثل $.grep وإذا كان هناك كائن واحد هو معرفة ، ستعود الدالة الكائن ، بدلاً من صفيف.


لدى Underscore.js طريقة لطيفة لذلك:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })

نسخة عامة وأكثر مرونة من وظيفة findById أعلاه:

// array = [{key:value},{key:value}]
function objectFindByKey(array, key, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
    return null;
}

var array = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var result_obj = objectFindByKey(array, 'id', '45');

يمكنك استخدام الفلاتر ،

  function getById(id, myArray) {
    return myArray.filter(function(obj) {
      if(obj.id == id) {
        return obj 
      }
    })[0]
  }

get_my_obj = getById(73, myArray);


يمكنك تجربة Sugarjs من http://sugarjs.com/ .

لديه طريقة حلوة جدا على المصفوفات ،. لذلك يمكنك العثور على عنصر مثل هذا:

array.find( {id: 75} );

يمكنك أيضًا تمرير كائن به المزيد من الخصائص لإضافة "جملة-مكان" آخر.

لاحظ أن Sugarjs يمتد الكائنات المحلية ، وبعض الناس يعتبرون هذا الشر ...


يوفر ECMAScript 2015 طريقة find() في المصفوفات:

var myArray = [
 {id:1, name:"bob"},
 {id:2, name:"dan"},
 {id:3, name:"barb"},
]

// grab the Array item which matchs the id "2"
var item = myArray.find(item => item.id === 2);

// print
console.log(item.name);

يعمل بدون مكتبات خارجية. ولكن إذا كنت تريد دعمًا أقدم للمتصفح ، فقد ترغب في تضمين هذا العنوان .


myArray.find(x => x.id === '45').foo;

من MDN:

تقوم طريقة find() بإرجاع قيمة في الصفيف ، إذا كان عنصر في الصفيف يفي بوظيفة الاختبار المقدمة. على خلاف ذلك يتم إرجاع غير undefined .

إذا كنت ترغب في الحصول على مجموعة من عناصر المطابقة ، استخدم طريقة filter() بدلاً من ذلك:

myArray.filter(x => x.id === '45');

هذا سيعود مجموعة من الكائنات. إذا كنت ترغب في الحصول على مجموعة من خصائص foo ، يمكنك القيام بذلك باستخدام طريقة map() :

myArray.filter(x => x.id === '45').map(x => x.foo);

ملاحظة جانبية: طرق مثل find() أو filter() ، ووظائف الأسهم غير مدعومة من قبل المتصفحات الأقدم (مثل IE) ، لذلك إذا كنت تريد دعم هذه المتصفحات ، يجب عليك تحويل الشفرة الخاصة بك باستخدام Babel .





javascript-objects