Как определить, содержит ли массив 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 ]

4 голосов
/ 12 октября 2013

если вы используете jquery, вы можете воспользоваться grep для создания массива со всеми соответствующими объектами:

var results = $.grep(vendors, function (e) {
    return e.Name == "Magenic";
});

, а затем использовать массив результатов:

for (var i=0, l=results.length; i<l; i++) {
    console.log(results[i].ID);
}
4 голосов
/ 21 ноября 2011

Вы должны зацикливаться, нет никакого способа обойти это.

function seekVendor(vendors, name) {
  for (var i=0, l=vendors.length; i<l; i++) {
    if (typeof vendors[i] == "object" && vendors[i].Name === name) {
      return vendors[i];
    }
  }
}

Конечно, вы можете использовать библиотеку типа linq.js , чтобы сделать это более приятным:

Enumerable.From(vendors).Where("$.Name == 'Magenic'").First();

(см. jsFiddle для демонстрации)

Я сомневаюсь, что linq.js будет быстрее, чем прямой цикл, но он определенно будет более гибким, когда что-то получитсянемного сложнее.

1 голос
/ 17 января 2018

Вы можете использовать lodash .Если библиотека lodash слишком велика для вашего приложения, рассмотрите возможность разделения ненужной функции.

let newArray = filter(_this.props.ArrayOne, function(item) {
                    return find(_this.props.ArrayTwo, {"speciesId": item.speciesId});
                });

Это всего лишь один из способов сделать это.Другой может быть:

var newArray=  [];
     _.filter(ArrayOne, function(item) {
                        return AllSpecies.forEach(function(cItem){
                            if (cItem.speciesId == item.speciesId){
                            newArray.push(item);
                          }
                        }) 
                    });

console.log(arr);

Приведенный выше пример также можно переписать без использования каких-либо библиотек , таких как:

var newArray=  [];
ArrayOne.filter(function(item) {
                return ArrayTwo.forEach(function(cItem){
                    if (cItem.speciesId == item.speciesId){
                    newArray.push(item);
                  }
                }) 
            });
console.log(arr);

Надеюсь, мой ответ поможет.

1 голос
/ 22 мая 2017

Поправь меня, если я ошибаюсь .. я мог бы использовать forEach метод, подобный этому,

var found=false;
vendors.forEach(function(item){
   if(item.name === "name"){
       found=true;
       return;
   }
});

В настоящее время я привык к этому, из-за его простоты и самоочевидного слова. Спасибо.

1 голос
/ 04 декабря 2018

Чтобы сравнить один объект с другим, я объединяю цикл for (используется для циклического прохождения объектов) и some ().Вам не нужно беспокоиться о выходе массива за пределы границ и т. Д., Чтобы сохранить некоторый код.Документацию по .some можно найти здесь

var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];    
var  objectsFound = [];

for(let objectNumber in productList){
    var currentId = productList[objectNumber].id;   
    if (theDatabaseList.some(obj => obj.id === currentId)) {
        // Do what you need to do with the matching value here
        objectsFound.push(currentId);
    }
}
console.log(objectsFound);

Альтернативный способ сравнения одного объекта с другим - использование вложенного цикла for с Object.keys (). Length для полученияколичество объектов в массиве.Код ниже:

var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];    
var objectsFound = [];

for(var i = 0; i < Object.keys(productList).length; i++){
        for(var j = 0; j < Object.keys(theDatabaseList).length; j++){
        if(productList[i].id === theDatabaseList[j].id){
            objectsFound.push(productList[i].id);
        }       
    }
}
console.log(objectsFound);

Чтобы ответить на ваш точный вопрос, если вы просто ищете значение в объекте, вы можете использовать один цикл for.

var vendors = [
    {
      Name: 'Magenic',
      ID: 'ABC'
     },
    {
      Name: 'Microsoft',
      ID: 'DEF'
    } 
];

for(var ojectNumbers in vendors){
    if(vendors[ojectNumbers].Name === 'Magenic'){
        console.log('object contains Magenic');
    }
}
0 голосов
/ 15 июня 2019

Тестирование элементов массива:

JS Предлагает функции массива, которые позволяют вам достичь этого относительно легко.Они следующие:

  1. Array.prototype.filter: принимает функцию обратного вызова, которая является тестом, затем массив повторяется с помощью обратного вызова и фильтруется в соответствии с этим обратным вызовом. Возвращается новый отфильтрованный массив.
  2. Array.prototype.some: принимает функцию обратного вызова, которая является тестом, затем массив повторяется с помощью callback и , если какой-либо элемент проходитtest, возвращается логическое значение true.В противном случае возвращается false

Подробности лучше всего объяснить на примере:

Пример:

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

// filter returns a new array, we instantly check if the length 
// is longer than zero of this newly created array
if (vendors.filter(company => company.Name === 'Magenic').length ) {
  console.log('I contain Magenic');
}

// some would be a better option then filter since it directly returns a boolean
if (vendors.some(company => company.Name === 'Magenic')) {
  console.log('I also contain Magenic');
}

Поддержка браузера:

Эти две функции ES6, не все браузеры могут их поддерживать.Чтобы преодолеть это, вы можете использовать полифилл.Вот такое заполнение для Array.prototype.some (из MDN):

if (!Array.prototype.some) {
  Array.prototype.some = function(fun, thisArg) {
    'use strict';

    if (this == null) {
      throw new TypeError('Array.prototype.some called on null or undefined');
    }

    if (typeof fun !== 'function') {
      throw new TypeError();
    }

    var t = Object(this);
    var len = t.length >>> 0;

    for (var i = 0; i < len; i++) {
      if (i in t && fun.call(thisArg, t[i], i, t)) {
        return true;
      }
    }

    return false;
  };
}
0 голосов
/ 05 марта 2016

Я бы предпочел использовать регулярные выражения.

Если ваш код выглядит следующим образом,

vendors = [
    {
      Name: 'Magenic',
      ID: 'ABC'
     },
    {
      Name: 'Microsoft',
      ID: 'DEF'
    }
];

Я бы порекомендовал

/"Name":"Magenic"/.test(JSON.stringify(vendors))
0 голосов
/ 31 января 2019

Мой подход к решению этой проблемы заключается в использовании ES6 и создании функции, которая выполняет проверку за нас.Преимущество этой функции заключается в том, что она может быть многократно использована в вашем проекте для проверки любого массива объектов с учетом key и value для проверки.

Массив

const ceos = [
  {
    name: "Jeff Bezos",
    company: "Amazon"
  }, 
  {
    name: "Mark Zuckerberg",
    company: "Facebook"
  }, 
  {
    name: "Tim Cook",
    company: "Apple"
  }
];

Функция

const arrayIncludesInObj = (arr, key, valueToCheck) => {
  let found = false;

  arr.some(value => {
    if (value[key] === valueToCheck) {
      found = true;
      return true; // this will break the loop once found
    }
  });

  return found;
}

Вызов / использование

const found = arrayIncludesInObj(ceos, "name", "Tim Cook"); // true

const found = arrayIncludesInObj(ceos, "name", "Tim Bezos"); // false
0 голосов
/ 01 марта 2018

В качестве альтернативы вы можете сделать:

const find = (key, needle) => return !!~vendors.findIndex(v => (v[key] === needle));
0 голосов
/ 19 апреля 2018

var without2 = (arr, args) => arr.filter(v => v.id !== args.id); Пример:

without2([{id:1},{id:1},{id:2}],{id:2})

Результат: without2 ([{ID: 1}, {ID: 1}, {ID: 2}], {ID: 2})

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...