我有一个数组

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

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


当前回答

2021解决方案*

Lodash .some (docs)是一个干净的解决方案,如果你使用_matchesProperty (docs)速记:

_.some(VENDORS, ['Name', 'Magenic'])

解释

这将遍历供应商数组,寻找Name键值为字符串'Magenic'的元素对象。一旦找到这个元素,它就返回true并停止迭代。如果在遍历整个数组后仍未找到该元素,则返回false。

代码片段

const vendor =[{名称:'Magenic', ID: 'ABC'},{名称:'Microsoft', ID: 'DEF'}]; console.log(_。some(vendor, ['Name', 'Magenic']));/ /正确的 < script src = " https://cdn.jsdelivr.net/npm/lodash@4.17.20 lodash.min.js " > < /脚本>

*注意,这使用流行的lodash库来实现最简单/最短的解决方案。对于那些感兴趣的人,我提供这个作为现有香草JS解决方案的替代方案。

其他回答

根据ECMAScript 6规范,您可以使用findIndex。

const magenicIndex =供应商。findIndex(供应商=>供应商。= = = ' Magenic')名称;

magenicIndex将保留0(这是数组中的索引)或-1(如果没有找到)。

如果我错了请指正。 我可以像这样使用每种方法,

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

   }
});

现在我已经习惯了,因为它简单明了。 谢谢你!

因为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');

不需要循环。我想到了三种方法:

Array.prototype.some ()

这是对你的问题最准确的回答。"check if something exists",表示bool类型的结果。如果有任何“Magenic”物体,这将是正确的,否则为假:

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

Array.prototype.filter ()

这将返回一个包含所有“Magenic”对象的数组,即使只有一个(将返回一个单元素数组):

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

如果你试图将其强制为布尔值,它将不起作用,因为空数组(没有'Magenic'对象)仍然为真。所以使用魔法供应商。条件句中的长度。

Array.prototype.find ()

这将返回第一个“Magenic”对象(如果没有,则未定义):

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

这将强制转换为布尔值(任何对象为真,未定义为假)。


注意:我使用vendor[“名称”]而不是vendor。名称,因为属性名的大小写很奇怪。

注意2:在检查名称时,没有理由使用松散相等(==)而不是严格相等(===)。