Javascript. Проверьте, содержит ли объект object

#javascript

#javascript

Вопрос:

У меня есть следующие два массива объектов

 //references
var refs=[
         {id:1,   name:'John',    state:'A'},
         {id:2,   name:'Obama',   state:'P'},
         {id:3,   name:'Lincoln', state:'P'}
];

//items
var items=[
          {ref:refs[0],    detailed:true },
          {ref:refs[1],    detailed:false}
];
  

Теперь я хочу проверить, содержит ли items ссылки[0] . Как я могу это сделать? Конечно, мы можем сделать
что-то вроде этого

 for(item:items){
 if(item.ref==refs[0]){
  console.log('contains');
  break;
 }
}
  

но у меня может быть 2000 ссылок. Есть идеи. Спасибо

Комментарии:

1. Можете ли вы пояснить, почему этот подход не будет работать, если у вас 2000 ссылок?

2. Как наличие большего количества ссылок что-либо меняет, в любом случае вас интересуют только ссылки [0] в соответствии с вашими спецификациями? Я бы не стал проходить через цикл for in, хотя, потому что и элементы, и ссылки являются массивами, поэтому вы можете сделать while( i<len) , поскольку элементы[?].ссылки — это ссылка, с которой вы можете сравнить вот так ===

3. Нет, это работает. Мне просто кажется, что это пустая трата ресурсов.

4. @JumabekAlihanov — Смотрите мой комментарий к Юхане под моим ответом.

5. Все еще не уверен, каковы требования, если вам нужно просмотреть только один элемент один раз, тогда цикл — это путь, но если у вас много ссылок, и вам нужно знать, есть ли они в элементах, и если да, то каковы значения, тогда вам нужно переопределить элементы. Я обновил свой ответ с возможной оптимизацией.

Ответ №1:

Вы можете использовать Array.filter() :

 console.log(get_ref_item(refs[0], items));

function get_ref_item(ref, items) {
    return items.filter(function fi(item){
        return ref.id == item.ref.id;
    });
}
  

http://jsfiddle.net/5MfrT/

Комментарии:

1. Обратите внимание, что это практически идентично исходному коду с точки зрения производительности. Просто нет способа избежать перебора всего массива при поиске элементов, если вы уже примерно не знаете, с чего начать поиск.

2. @Juhana — С точки зрения производительности , for с разрывом во многих случаях будет быстрее, в зависимости от того, где в массиве находится искомый элемент. Итак, на самом деле, код OPs лучше в этом отношении. Смотрите: jsperf.com/for-vs-array-filter

3. Обратите внимание, единственная причина, по которой он мог быть эквивалентным (или, может быть, лучше, пришлось бы тестировать), заключается в том, что каждый раз нужно искать во всем массиве, например, если ref.id может существовать более одного раза в массиве.

Ответ №2:

Не ясно, в чем здесь проблема, но предполагая, что вы хотели бы знать, есть ли ссылка в элементах, и вам нужно знать это для нескольких ссылок (просматривайте это несколько раз), тогда вам лучше переопределить свои элементы:

 //references
var refs=[
         {id:1,   name:'John',    state:'A'},
         {id:2,   name:'Obama',   state:'P'},
         {id:3,   name:'Lincoln', state:'P'}
];

//items
var items=[
          {ref:refs[0],    detailed:true },
          {ref:refs[1],    detailed:false}
];

//if you need to continiously look up a ref in items
// it's better to convert items to an object
// {"refid":{ref:..,detailed:...}}
// assuming every item has a ref and has that ref only once
// and every ref has a unique id
var i = -1,len=items.length,tmp={};
while(  i<len){
  tmp[items[i].ref.id]=items[i];
}
items=tmp;

console.log("item for refs 0:",items[refs[0].id]);
console.log("item for refs 1:",items[refs[1].id]);
console.log("item for refs 2:",items[refs[2].id]);//undefined, that ref is not it items
  

Комментарии:

1. Вы можете протестировать свою оптимизацию на основе методов for и Array.filter здесь: jsperf.com/for-vs-array-filter Настройка тестов производительности может быть сложной задачей, поэтому обязательно продумайте это до конца.

2. @JaredFarrish Я не использую for ... in nor Array.filter или while( i<len) , потому что он вообще не использует массив. Но я могу сказать вам прямо сейчас, что если бы у вас было более 500 элементов и более 2000 ссылок, делающих элементы объектом с ref.id as keys собирается выполнить любой поиск в массиве, который вы планируете выполнить 200 раз. (если op планировал сопоставить каждый элемент с ссылкой)