我有一个数组

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

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


当前回答

数组元素测试:

JS提供了数组函数,允许你相对容易地实现这一点。它们是:

array .prototype.filter:接受一个回调函数,这个回调函数是一个测试,然后数组被迭代,并根据这个回调进行过滤。返回一个新的过滤数组。 array .prototype.some:接受一个回调函数,它是一个测试,然后使用is callback迭代数组,如果任何元素通过测试,则返回布尔值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; }; }

其他回答

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

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

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

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

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

const a = [{one:2},{two:2},{two:4}]
const b = a.filter(val => "two" in val).length;
if (b) {
   ...
}

如果你正在使用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);
}

数组元素测试:

JS提供了数组函数,允许你相对容易地实现这一点。它们是:

array .prototype.filter:接受一个回调函数,这个回调函数是一个测试,然后数组被迭代,并根据这个回调进行过滤。返回一个新的过滤数组。 array .prototype.some:接受一个回调函数,它是一个测试,然后使用is callback迭代数组,如果任何元素通过测试,则返回布尔值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; }; }

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

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:在检查名称时,没有理由使用松散相等(==)而不是严格相等(===)。