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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8217419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:10:02  来源:igfitidea点击:

How to determine if Javascript array contains an object with an attribute that equals a given value?

javascriptarrays

提问by David Lozzi

I have an array like

我有一个像

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

How do I check this array to see if Magenic exists? I don't want to loop, unless I have to. I'm working with potentially a couple thousand records.

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



UPDATED

更新

Since this has been a popular post, I thought I'd share something new I found. And it appears @CAFxX has already shared this! I should read these more often. I came across https://benfrain.com/understanding-native-javascript-array-methods/.

由于这是一个受欢迎的帖子,我想我会分享一些我发现的新东西。看来@CAFxX 已经分享了这个!我应该多读读这些。我遇到了https://benfrain.com/understanding-native-javascript-array-methods/

vendors.filter(function(vendor){ return vendor.Name === "Magenic" })

And with ECMAScript 2015it is even simpler using the new arrow functions:

ECMAScript 2015 中,使用新的箭头函数更加简单:

vendors.filter(vendor => vendor.Name === "Magenic")

采纳答案by Alex Turpin

2018 edit: This answer is from 2011, before browsers had widely supported array filtering methods and arrow functions. Have a look at CAFxX's answer.

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

There is no "magic" way to check for something in an array without a loop. Even if you use some function, the function itself will use a loop. What you can do is break out of the loop as soon as you find what you're looking for to minimize computational time.

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

var found = false;
for(var i = 0; i < vendors.length; i++) {
    if (vendors[i].Name == 'Magenic') {
        found = true;
        break;
    }
}

回答by CAFxX

No need to reinvent the wheelloop, at least not explicitly (using arrow functions, modern browsers only):

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

if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
  /* vendors contains the element we're looking for */
}

or, better yet:

或者,更好的是

if (vendors.some(e => e.Name === 'Magenic')) {
  /* vendors contains the element we're looking for */
}

EDIT: If you need compatibility with lousy browsers then your best bet is:

编辑:如果您需要与糟糕的浏览器兼容,那么您最好的选择是:

if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
  /* vendors contains the element we're looking for */
}

回答by boxtrain

No loop necessary. Three methods that come to mind:

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

Array.prototype.some()

Array.prototype.some()

This is the most exact answer for your question, i.e. "check if something exists", implying a bool result. This will be true if there are any 'Magenic' objects, false otherwise:

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

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

Array.prototype.filter()

Array.prototype.filter()

This will return an array of all 'Magenic' objects, even if there is only one (will return a one-element array):

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

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

If you try to coerce this to a boolean, it will not work, as an empty array (no 'Magenic' objects) is still truthy. So just use magenicVendors.lengthin your conditional.

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

Array.prototype.find()

Array.prototype.find()

This will return the first 'Magenic' object (or undefinedif there aren't any):

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

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

This coerces to a boolean okay (any object is truthy, undefinedis falsy).

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



Note: I'm using vendor["Name"] instead of vendor.Name because of the weird casing of the property names.

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

Note 2: No reason to use loose equality (==) instead of strict equality (===) when checking the name.

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

回答by TeaCoder

The accepted answer still works but now we have an ECMAScript 6 native method [Array.find][1]to achieve the same effect.

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

Quoting MDN:

引用 MDN:

The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

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

var arr = []; 
var item = {
  id: '21',
  step: 'step2',
  label: 'Banana',
  price: '19$'
};

arr.push(item);
/* 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
}

See my jsfiddle linkThere is a polyfill for IE provided by mozilla

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

回答by Mirza Leka

Here's the way I'd do it

这是我要做的方式

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

array.some()method checks if there is at least one value in an array that matches criteria and returns a boolean. From here on you can go with:

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

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

回答by Keith.Abramo

Unless you want to restructure it like this:

除非你想像这样重构它:

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

to which you can do if(vendors.Magnetic)

你可以做的 if(vendors.Magnetic)

You will have to loop

你将不得不循环

回答by Lucas Bento

As per ECMAScript 6 specification, you can use findIndex.

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

const magenicIndex = vendors.findIndex(vendor => vendor.Name === 'Magenic');

const magenicIndex = vendors.findIndex(vendor => vendor.Name === 'Magenic');

magenicIndexwill hold either 0(which is the index in the array) or -1if it wasn't found.

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

回答by Jay Chakra

As the OP has asked the question if the key exists or not.

由于 OP 已经询问了密钥是否存在的问题。

A more elegant solution that will return boolean using ES6 reduce function can be

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

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

Note:The initial parameter of reduce is a falseand if the array has the key it will return true.

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

Hope it helps for better and cleaner code implementation

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

回答by jAndy

You cannot without looking into the object really.

你不能不仔细观察对象。

You probably should change your structure a little, like

你可能应该稍微改变你的结构,比如

vendors = {
    Magenic:   'ABC',
    Microsoft: 'DEF'
};

Then you can just use it like a lookup-hash.

然后你可以像查找哈希一样使用它。

vendors['Microsoft']; // 'DEF'
vendors['Apple']; // undefined

回答by Tomalak

You have to loop, there is no way around it.

你必须循环,没有办法绕过它。

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];
    }
  }
}

Of course you could use a library like linq.jsto make this more pleasing:

当然,您可以使用linq.js 之类的库来使这更令人愉悦:

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

(see jsFiddlefor a demo)

(有关演示,请参阅jsFiddle

I doubt that linq.js will be faster than a straight-forward loop, but it certainly is more flexible when things get a little more complicated.

我怀疑 linq.js 会比直接循环更快,但当事情变得更复杂时,它肯定会更灵活。