Как определить, содержит ли массив Javascript объект с атрибутом, равным заданному значению? - PullRequest
456 голосов
/ 21 ноября 2011

У меня есть массив как

vendors = [
    {
      Name: 'Magenic',
      ID: 'ABC'
     },
    {
      Name: 'Microsoft',
      ID: 'DEF'
    } //and so on goes array... 
];

Как проверить этот массив, чтобы увидеть, существует ли Magenic? Я не хочу зацикливаться, если я не должен. Я работаю с потенциально несколькими тысячами записей.

ОБНОВЛЕНО

Поскольку это был популярный пост, я решил поделиться чем-то новым, что нашел. И, кажется, @CAFxX уже поделился этим! Я должен читать это чаще. Я наткнулся https://benfrain.com/understanding-native-javascript-array-methods/.

vendors.filter(function(vendor){ return vendor.Name === "Magenic" });

А с ECMAScript 2015 еще проще использовать новые функции стрелок:

vendors.filter(vendor => (vendor.Name === "Magenic"));

Ответы [ 21 ]

658 голосов
/ 21 ноября 2011

Нет необходимости заново изобретать цикл wheel , по крайней мере, явно (используя функции стрелок , только в современных браузерах ):

if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
  /* vendors contains the element we're looking for */
}

или, еще лучше :

if (vendors.some(e => e.Name === 'Magenic')) {
  /* vendors contains the element we're looking for */
}

РЕДАКТИРОВАТЬ: Если вам нужна совместимость с паршивыми браузерами, то ваш лучший выбор:

if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
  /* vendors contains the element we're looking for */
}
215 голосов
/ 21 ноября 2011

2018 edit : Этот ответ с 2011 года, до того, как браузеры широко поддерживали методы фильтрации массива и функции стрелок.Посмотрите на ответ CAFxX .

Не существует "волшебного" способа проверить что-либо в массиве без цикла.Даже если вы используете какую-то функцию, сама функция будет использовать цикл.Что вы можете сделать, так это выйти из цикла, как только вы найдете то, что ищете, чтобы минимизировать время вычислений.

var found = false;
for(var i = 0; i < vendors.length; i++) {
    if (vendors[i].Name == 'Magenic') {
        found = true;
        break;
    }
}
62 голосов
/ 06 декабря 2016

Нет необходимости в петле.На ум приходят три метода:

Array.prototype.some ()

Это самый точный ответ на ваш вопрос, то есть «проверь, существует ли что-то»,подразумевая результат bool.Это будет верно, если есть какие-либо объекты Magenic, иначе false:

let hasMagenicVendor = vendors.some( vendor => vendor['Name'] === 'Magenic' )

Array.prototype.filter ()

Это вернет массиввсе объекты Magenic, даже если есть только один (вернет одноэлементный массив):

let magenicVendors = vendors.filter( vendor => vendor['Name'] === 'Magenic' )

Если вы попытаетесь привести это к логическому значению, он не будет работать, как пустой массив(никаких «магических» объектов) все еще правдива.Так что просто используйте magenicVendors.length в вашем условном выражении.

Array.prototype.find ()

Это вернет первый объект "Magenic" (или undefined, еслиих нет):

let magenicVendor = vendors.find( vendor => vendor['Name'] === 'Magenic' );

Это приводит к булеву окей (любой объект правдивый, undefined фальшивый).


Примечание: я используюvendor ["Name"] вместо vendor.Name из-за странного ввода имен свойств.

Примечание 2: Нет причин использовать свободное равенство (==) вместо строгого равенства (===), когдапроверка имени.

41 голосов
/ 05 марта 2016

Принятый ответ все еще работает, но теперь у нас есть собственный метод ECMAScript 6 [Array.find][1] для достижения того же эффекта.

Цитирование MDN:

Метод find () возвращает значение первого элемента в массиве что удовлетворяет предоставленной функции тестирования. В противном случае не определено вернулся.

var arr = []; 
var item = {
  id: '21',
  step: 'step2',
  label: 'Banana',
  price: '19$'
};

arr.push(item);
/* note : data is the actual object that matched search criteria 
  or undefined if nothing matched */
var data = arr.find( function( ele ) { 
    return ele.id === '21';
} );

if( data ) {
 console.log( 'found' );
 console.log(data); // This is entire object i.e. `item` not boolean
}

См. Мою ссылку jsfiddle Для IE имеется полизаполнение, предоставляемое mozilla

19 голосов
/ 21 ноября 2011

Если вы не хотите реструктурировать это так:

vendors = {
    Magenic: {
      Name: 'Magenic',
      ID: 'ABC'
     },
    Microsoft: {
      Name: 'Microsoft',
      ID: 'DEF'
    } and so on... 
};

на который вы можете сделать if(vendors.Magnetic)

Вам придется зацикливаться

18 голосов
/ 29 января 2017

Согласно спецификации ECMAScript 6, вы можете использовать findIndex.

const magenicIndex = vendors.findIndex(vendor => vendor.Name === 'Magenic');

magenicIndex будет содержать либо 0 (что являетсяиндекс в массиве) или -1, если он не был найден.

16 голосов
/ 29 ноября 2018

Вот как я бы это сделал

const found = vendors.some(item => item.Name === 'Magenic');

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

if (found) {
// do something
} else {
// do something else
}
13 голосов
/ 21 ноября 2011

Вы не можете, не глядя на объект на самом деле.

Вы, вероятно, должны немного изменить свою структуру, как

vendors = {
    Magenic:   'ABC',
    Microsoft: 'DEF'
};

Тогда вы можете просто использовать его как хеш для поиска.

vendors['Microsoft']; // 'DEF'
vendors['Apple']; // undefined
11 голосов
/ 21 августа 2018

Поскольку ОП задал вопрос , существует ли ключ .

Более элегантное решение, которое будет возвращать логическое значение с использованием функции уменьшения ES6, может быть

const magenicVendorExists =  vendors.reduce((accumulator, vendor) => (accumulator||vendor.Name === "Magenic"), false);

Примечание: Начальным параметром снижения является false иу массива есть ключ, который он вернет true.

Надеюсь, это поможет для лучшей и более чистой реализации кода

4 голосов
/ 14 мая 2019

Вы можете попробовать это для меня.

const _ = require('lodash');

var arr = [
  {
    name: 'Jack',
    id: 1
  },
  {
    name: 'Gabriel',
    id: 2
  },
  {
    name: 'John',
    id: 3
  }
]

function findValue(arr,value) {
  return _.filter(arr, function (object) {
    return object['name'].toLowerCase().indexOf(value.toLowerCase()) >= 0;
  });
}

console.log(findValue(arr,'jack'))
//[ { name: 'Jack', id: 1 } ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...