我有一个数组

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

我如何检查这个数组,看看“Magenic”是否存在?我不想循环,除非迫不得已。我可能要处理几千条记录。


当前回答

因为OP询问了密钥是否存在的问题。

使用ES6 reduce函数返回布尔值的更优雅的解决方案可以是

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

注意:reduce的初始参数是false,如果数组有键,它将返回true。

希望它有助于更好和更清晰的代码实现

其他回答

接受的答案仍然有效,但现在我们有一个ECMAScript 6本机方法[数组。find][1]和[数组。有些][2]来达到同样的效果。

Array.some

如果你只想确定一个元素是否存在,也就是说,你需要一个真/假的判断。

引用中数:

some()方法测试数组中是否至少有一个元素通过了所提供函数实现的测试。如果在数组中,它找到了提供的函数返回true的元素,则返回true;否则返回false。它不会修改数组。

Array.find

如果你想从数组else中获得匹配的对象,则使用find返回undefined。

引用中数:

find()方法返回所提供数组中满足所提供测试函数的第一个元素的值。如果没有满足测试函数的值,则返回undefined。

var arr = [
  {
    id: 21,
    label: 'Banana',
  },
  {
    id: 22,
    label: 'Apple',
  }
]

/* 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
}


/* note : doesExist is a boolean thats true or false depending on of whether the data was found or not */
var doesExist = arr.some(function(ele) {
    return ele.id === 21;
});


有一个由mozilla提供的IE的polyfill

我宁愿用正则表达式。

如果您的代码如下所示,

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

我推荐

/"Name":"Magenic"/.test(JSON.stringify(vendors))

为了比较一个对象和另一个对象,我结合了for in循环(用于遍历对象)和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);

我比较一个对象和另一个对象的另一种方法是使用object .keys()的嵌套for循环。长度来获取数组中对象的数量。下面的代码:

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 in循环。

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

因为OP询问了密钥是否存在的问题。

使用ES6 reduce函数返回布尔值的更优雅的解决方案可以是

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

注意:reduce的初始参数是false,如果数组有键,它将返回true。

希望它有助于更好和更清晰的代码实现

map、filter、find和类似的函数比简单的循环要慢。 对我来说,它们也比简单的循环更难读,更难调试。使用它们看起来像是一种非理性的仪式。

最好是这样的:

 arrayHelper = {
     arrayContainsObject: function (array, object, key){
         for (let i = 0; i < array.length; i++){
            if (object[key] === array[i][key]){
                 return true;
            }
         }
         return false;
     }
     
   };

在给定OP的例子中使用它:

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

let abcObject = {ID: 'ABC', Name: 'Magenic'};

let isContainObject = arrayHelper.arrayContainsObject(vendors, abcObject, 'ID');