Dav*_*zzi 538 javascript arrays
我有一个类似的数组
vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
} //and so on goes array...
];
Run Code Online (Sandbox Code Playgroud)
如何检查此数组以查看Magenic是否存在?我不想循环,除非我必须.我正在处理可能有几千条记录.
更新
由于这是一个受欢迎的帖子,我想我会分享一些新发现的东西.似乎@CAFxX已经分享了这个!我应该经常阅读这些内容.我遇到了https://benfrain.com/understanding-native-javascript-array-methods/.
vendors.filter(function(vendor){ return vendor.Name === "Magenic" });
Run Code Online (Sandbox Code Playgroud)
使用ECMAScript 2015,使用新的箭头功能更简单:
vendors.filter(vendor => (vendor.Name === "Magenic"));
Run Code Online (Sandbox Code Playgroud)
CAF*_*FxX 769
没有必要重新发明 轮循环,至少没有明确(使用箭头函数,仅现代浏览器):
if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
/* vendors contains the element we're looking for */
}
Run Code Online (Sandbox Code Playgroud)
或者,更好的是:
if (vendors.some(e => e.Name === 'Magenic')) {
/* vendors contains the element we're looking for */
}
Run Code Online (Sandbox Code Playgroud)
编辑:如果你需要与糟糕的浏览器兼容,那么你最好的选择是:
if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
/* vendors contains the element we're looking for */
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*pin 232
2018编辑:这个答案来自2011年,之前浏览器广泛支持阵列过滤方法和箭头功能.看看CAFxX的答案.
在没有循环的情况下,没有"神奇"的方法来检查数组中的某些东西.即使你使用某个函数,函数本身也会使用循环.您可以做的就是在找到所需内容时尽快摆脱循环,以最大限度地缩短计算时间.
var found = false;
for(var i = 0; i < vendors.length; i++) {
if (vendors[i].Name == 'Magenic') {
found = true;
break;
}
}
Run Code Online (Sandbox Code Playgroud)
box*_*ain 71
无需循环.想到的三种方法:
Array.prototype.some()
这是你问题的最准确答案,即"检查是否存在某种东西",这意味着一个bool结果.如果存在任何"Magenic"对象,则为true,否则为false:
let hasMagenicVendor = vendors.some( vendor => vendor['Name'] === 'Magenic' )
Run Code Online (Sandbox Code Playgroud)
Array.prototype.filter()
这将返回所有"Magenic"对象的数组,即使只有一个(将返回单元素数组):
let magenicVendors = vendors.filter( vendor => vendor['Name'] === 'Magenic' )
Run Code Online (Sandbox Code Playgroud)
如果你试图将它强制转换为布尔值,它将无法工作,因为一个空数组(没有'Magenic'对象)仍然是真的.所以只需magenicVendors.length
在条件中使用即可.
Array.prototype.find()
这将返回第一个'Magenic'对象(或者undefined
如果没有):
let magenicVendor = vendors.find( vendor => vendor['Name'] === 'Magenic' );
Run Code Online (Sandbox Code Playgroud)
这强制到布尔值(任何对象都是真实的,undefined
是假的).
注意:由于属性名称的奇怪外壳,我使用供应商["Name"]而不是vendor.Name.
注2:检查名称时没有理由使用松散等式(==)而不是严格相等(===).
Tea*_*der 41
接受的答案仍然有效,但现在我们有一个ECMAScript 6本机方法[Array.find][1]
来实现相同的效果.
引用MDN:
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
}
Run Code Online (Sandbox Code Playgroud)
请参阅我的jsfiddle链接有一个由mozilla提供的 IE的polyfill
Kei*_*amo 21
除非你想像这样重组它:
vendors = {
Magenic: {
Name: 'Magenic',
ID: 'ABC'
},
Microsoft: {
Name: 'Microsoft',
ID: 'DEF'
} and so on...
};
Run Code Online (Sandbox Code Playgroud)
你能做到的 if(vendors.Magnetic)
你将不得不循环
Mir*_*eka 21
这是我做的方式
const found = vendors.some(item => item.Name === 'Magenic');
Run Code Online (Sandbox Code Playgroud)
array.some()
方法检查数组中是否至少有一个值与条件匹配并返回一个布尔值.从这里你可以去:
if (found) {
// do something
} else {
// do something else
}
Run Code Online (Sandbox Code Playgroud)
Aki*_*oni 20
可能为时已晚,但 javascript 数组有两个方法some
和every
返回布尔值的方法,可以帮助您实现这一目标。
我认为some
最适合您打算实现的目标。
vendors.some( vendor => vendor['Name'] !== 'Magenic' )
Run Code Online (Sandbox Code Playgroud)
有些验证数组中的任何对象满足给定条件。
vendors.every( vendor => vendor['Name'] !== 'Magenic' )
Run Code Online (Sandbox Code Playgroud)
Every 验证数组中的所有对象都满足给定条件。
Jay*_*kra 15
由于OP已经询问密钥是否存在.
一个更优雅的解决方案,将使用ES6 reduce函数返回布尔值
const magenicVendorExists = vendors.reduce((accumulator, vendor) => (accumulator||vendor.Name === "Magenic"), false);
Run Code Online (Sandbox Code Playgroud)
注意: reduce的初始参数是a false
,如果数组有键,它将返回true.
希望它有助于更好,更清晰的代码实现
jAn*_*ndy 13
你不能没有真正地看着对象.
你可能应该改变你的结构,比如
vendors = {
Magenic: 'ABC',
Microsoft: 'DEF'
};
Run Code Online (Sandbox Code Playgroud)
然后你可以像查询哈希一样使用它.
vendors['Microsoft']; // 'DEF'
vendors['Apple']; // undefined
Run Code Online (Sandbox Code Playgroud)
JS 提供了数组函数,可以让你相对容易地实现这一点。它们如下:
Array.prototype.filter
: 接受一个作为测试的回调函数,然后使用 is callback 迭代数组并根据此回调进行过滤。返回一个新的过滤数组。Array.prototype.some
:接受一个作为测试的回调函数,然后使用 is 回调迭代数组,如果任何元素通过测试, 则返回布尔值 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');
}
Run Code Online (Sandbox Code Playgroud)
这 2 个函数是ES6
函数,并非所有浏览器都支持它们。为了克服这个问题,您可以使用 polyfill。这是Array.prototype.some
(来自 MDN)的 polyfill :
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;
};
}
Run Code Online (Sandbox Code Playgroud)
小智 9
const check = vendors.find((item)=>item.Name==='Magenic')
console.log(check)
Run Code Online (Sandbox Code Playgroud)
试试这个代码。
如果项目或元素存在,则输出将显示该元素。如果它不存在,则输出将为“未定义”。
迄今为止最简单的方法:
if (vendors.findIndex(item => item.Name == "Magenic") == -1) {
//not found item
} else {
//found item
}
Run Code Online (Sandbox Code Playgroud)
我解决这个问题的方法是使用 ES6 并创建一个函数来为我们进行检查。此函数的好处是,它可以在整个项目中重复使用,以检查给定的任何对象数组key
和value
要检查的对象。
说得够多了,让我们看看代码
大批
const ceos = [
{
name: "Jeff Bezos",
company: "Amazon"
},
{
name: "Mark Zuckerberg",
company: "Facebook"
},
{
name: "Tim Cook",
company: "Apple"
}
];
Run Code Online (Sandbox Code Playgroud)
功能
const arrayIncludesInObj = (arr, key, valueToCheck) => {
return arr.some(value => value[key] === valueToCheck);
}
Run Code Online (Sandbox Code Playgroud)
通话/使用
const found = arrayIncludesInObj(ceos, "name", "Tim Cook"); // true
const found = arrayIncludesInObj(ceos, "name", "Tim Bezos"); // false
Run Code Online (Sandbox Code Playgroud)
函数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;
}
};
Run Code Online (Sandbox Code Playgroud)
并像这样使用给定的 OP 示例:
vendors = [{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
}
];
let abcObject = {ID: 'ABC', Name: 'Magenic'};
let isContainObject = arrayHelper.arrayContainsObject(vendors, abcObject, 'ID');
Run Code Online (Sandbox Code Playgroud)
您必须循环,无法解决。
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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您可以使用像linq.js这样的库来使此过程更令人愉悦:
Enumerable.From(vendors).Where("$.Name == 'Magenic'").First();
Run Code Online (Sandbox Code Playgroud)
(有关演示,请参见jsFiddle)
我怀疑linq.js会比直接循环更快,但是当事情变得更复杂时,它肯定会更灵活。
如果您使用jQuery,您可以利用 grep 创建包含所有匹配对象的数组:
var results = $.grep(vendors, function (e) {
return e.Name == "Magenic";
});
Run Code Online (Sandbox Code Playgroud)
然后使用结果数组:
for (var i=0, l=results.length; i<l; i++) {
console.log(results[i].ID);
}
Run Code Online (Sandbox Code Playgroud)
如果我错了请纠正我..我可以使用这样的forEach
方法,
var found=false;
vendors.forEach(function(item){
if(item.name === "name"){
found=true;
}
});
Run Code Online (Sandbox Code Playgroud)
现在我已经习惯了,因为它简单且不言自明。谢谢你。
Lodash .some
( docs ) 是一个干净的解决方案,如果您使用_matchesProperty
( docs ) 速记:
_.some(VENDORS, ['Name', 'Magenic'])
Run Code Online (Sandbox Code Playgroud)
这将遍历VENDORS
Array 以查找Name
具有 String 值的键的元素 Object 'Magenic'
。一旦找到这个元素,它就会返回true
并停止迭代。如果在查看整个 Array 后没有找到该元素,则返回false
。
const VENDORS = [{ Name: 'Magenic', ID: 'ABC' }, { Name: 'Microsoft', ID: 'DEF' }];
console.log(_.some(VENDORS, ['Name', 'Magenic'])); // true
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>
Run Code Online (Sandbox Code Playgroud)