如何确定Javascript数组是否包含具有等于给定值的属性的对象?

IT技术 javascript arrays
2021-01-29 14:25:40

我有一个像

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

如何检查此数组以查看“Magenic”是否存在?我不想循环,除非我必须。我正在处理可能有几千条记录。

6个回答

无需重新发明 车轮循环,至少不是明确的(使用箭头函数仅限现代浏览器):

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 */
}
@CAFxX 找到后如何获取索引?这甚至是一种可能性还是循环可以更好地获取索引?
2021-03-11 14:25:40
@7hibault 因为some一旦name === "Magenic"找到物体就会短路使用filter,它将检查每个项目直到数组末尾并创建一个与条件匹配的新数组项目,然后检查length
2021-03-11 14:25:40
很多关于.some. 现在是 2019 年,使用.some和使用 Polyfills 来支持糟糕的浏览器并继续你的生活...... polyfill.io/v3/url-builder。我唯一能看到的是,如果你不能支持箭头函数,那么它就像我提到的 Polyfill 一样简单,并且:arr.some(function(i) { return i.Name === "Magenic" })
2021-03-12 14:25:40
@Echtniet 如果您需要索引,那么 vendor.findIndex 将为您提供第一个匹配元素的索引。相反,如果您需要该值,则 vendor.find 将提供第一个匹配元素,或者 vendor.filter 将提供所有匹配元素。您可能需要参考developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-20 14:25:40
为什么some 更好呢
2021-03-23 14:25:40

2018 年编辑:这个答案来自 2011 年,在浏览器广泛支持数组过滤方法和箭头函数之前。看看CAFxX 的回答

没有“神奇”的方法可以在没有循环的情况下检查数组中的某些内容。即使您使用某个函数,该函数本身也会使用循环。您可以做的是在找到所需内容后立即跳出循环,以最大限度地减少计算时间。

var found = false;
for(var i = 0; i < vendors.length; i++) {
    if (vendors[i].Name == 'Magenic') {
        found = true;
        break;
    }
}
JSON.stringify(vendors).indexOf('Magenic') !== -1
2021-03-15 14:25:40
这些选项现在似乎有效:vendor.forEach、vendor.filter、vendor.reduce
2021-03-28 14:25:40
如果您只需要知道“某物”是否在其中,则不需要标志,您只需检查扫描索引的值和数组的大小。为此,当然需要在 for 语句之前声明索引 var。
2021-04-01 14:25:40
没问题。请记住,Keith 的解决方案也非常可行,可以避免循环。
2021-04-06 14:25:40
@LastBreath 如果'Magenic'在对象中的其他地方,很容易导致误报
2021-04-08 14:25:40

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

Array.prototype.some()

这是您问题的最准确答案,即“检查是否存在某些内容”,暗示布尔结果。如果有任何“Magenic”对象,则为真,否则为假:

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

Array.prototype.filter()

这将返回所有 'Magenic' 对象的数组,即使只有一个(将返回一个元素数组):

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

如果您尝试将其强制转换为布尔值,它将不起作用,因为空数组(没有“Magenic”对象)仍然是真实的。所以只需magenicVendors.length在您的条件中使用

Array.prototype.find()

这将返回第一个“Magenic”对象(或者undefined如果没有):

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

这会强制为一个布尔值 OK(任何对象都是真值,undefined是假值)。


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

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

需要指出的是,在幕后,这些都是循环的。这些在计算上也比简单的循环和执行操作慢。
2021-03-25 14:25:40
不妨去这里分享这份爱:stackoverflow.com/questions/21748670/...所以更多像我这样的人不要导航到那个旧页面并做出假设。
2021-04-06 14:25:40

接受的答案仍然有效,但现在我们有一个 ECMAScript 6 本地方法[Array.find][1][Array.some][2]达到相同的效果。

数组.some

使用some如果您只想确定一个元素是否存在,即您需要一个true/false确定。

引用 MDN:

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

数组查找

如果要从数组 else 返回匹配的对象,请使用 find undefined

引用 MDN:

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

var arr = [];
var item1 = {
    id: 21,
    label: 'Banana',
};
var item2 = {
    id: 22,
    label: 'Apple',
};
arr.push(item1, item2);

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


请参阅我的jsfiddle 链接Mozilla 提供了一个适用于 IE 的polyfill

此代码仅在以下情况下有效return ele.id === 21;它是一个数字,而不是一个字符串。
2021-03-16 14:25:40
谢谢!我的任务有点不同。获取数组中对象的索引 =>push if <0 || splice(index, 1)这是我的一些更新代码:const index = this.selected.indexOf(this.selected.find(s => s.id == passedObj.id))
2021-03-26 14:25:40
我认为重要的是要指出 'data' 的返回值(当 ele.id 匹配一个 id,例如 '21' 时)将是数组项本身(在这种情况下,整个项对象)。如果期望数据变量结果是“真”或“假”而不是假值,您会非常失望。
2021-04-01 14:25:40
很高兴有新的答案:) 只是想知道性能是否比上面的答案更好......
2021-04-03 14:25:40
如果你只是这样做return ele.id == '2'可能会更短,但对于一个好的 ES6 解决方案,+1。
2021-04-08 14:25:40

这是我要做的方式

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

array.some()方法检查数组中是否至少有一个值与条件匹配并返回一个布尔值。从这里开始,您可以使用:

if (found) {
// do something
} else {
// do something else
}