我有一个这样的数组:
[{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"},...]
如何在不迭代整个数组的情况下获取与条件匹配的对象的索引?
例如,给定prop2=="yutu"
,我想获得索引1
。
我看到了.indexOf()
,但认为它用于像["a1","a2",...]
这样的简单数组。我还检查了$.grep()
但这会返回对象,而不是索引。
答案 0 :(得分:525)
截至2016年,您应该使用Array.findIndex
(ES2015 / ES6标准):
a = [
{prop1:"abc",prop2:"qwe"},
{prop1:"bnmb",prop2:"yutu"},
{prop1:"zxvz",prop2:"qwrq"}];
index = a.findIndex(x => x.prop2 ==="yutu");
console.log(index);
谷歌Chrome,Firefox和Edge支持它。对于Internet Explorer,链接页面上有一个polyfill。
效果记录
函数调用很昂贵,因此对于非常大的数组,一个简单的循环将比findIndex
表现得更好:
let test = [];
for (let i = 0; i < 1e6; i++)
test.push({prop: i});
let search = test.length - 1;
let count = 100;
console.time('findIndex/predefined function');
let fn = obj => obj.prop === search;
for (let i = 0; i < count; i++)
test.findIndex(fn);
console.timeEnd('findIndex/predefined function');
console.time('findIndex/dynamic function');
for (let i = 0; i < count; i++)
test.findIndex(obj => obj.prop === search);
console.timeEnd('findIndex/dynamic function');
console.time('loop');
for (let i = 0; i < count; i++) {
for (let index = 0; index < test.length; index++) {
if (test[index].prop === search) {
break;
}
}
}
console.timeEnd('loop');
与大多数优化一样,只有在实际需要时才应谨慎应用。
答案 1 :(得分:24)
如何获得与条件匹配的对象索引(不沿数组迭代)?
你不能,某事必须遍历数组(至少一次)。
如果条件发生了很大变化,那么你必须循环并查看其中的对象,看它们是否符合条件。但是,在具有ES5功能的系统上(或者如果安装了垫片),可以相当简洁地完成该迭代:
var index;
yourArray.some(function(entry, i) {
if (entry.prop2 == "yutu") {
index = i;
return true;
}
});
它使用新的(ish)Array#some
function,它遍历数组中的条目,直到你给它的函数返回true。我给它的函数保存了匹配条目的索引,然后返回true
来停止迭代。
当然,只需使用for
循环即可。 this other answer中介绍了各种迭代选项。
但是如果你总是要为这个查找使用相同的属性,并且如果属性值是唯一的,你可以只循环一次并创建一个对象来映射它们:
var prop2map = {};
yourArray.forEach(function(entry) {
prop2map[entry.prop2] = entry;
});
(或者,您可以再次使用for
循环或任何your other options。)
然后,如果您需要找到prop2 = "yutu"
的条目,您可以这样做:
var entry = prop2map["yutu"];
我称之为“交叉索引”数组。当然,如果您删除或添加条目(或更改其prop2
值),您还需要更新映射对象。
答案 2 :(得分:20)
TJ Crowder所说的,无论如何都会有某种隐藏的迭代,lodash会变成:
var index = _.findIndex(array, {prop2: 'yutu'})
答案 3 :(得分:11)
var index;
yourArray.some(function (elem, i) {
return elem.prop2 === 'yutu' ? (index = i, true) : false;
});
迭代数组的所有元素。 它返回索引,如果条件不匹配,则返回true或false。
重要的是显式返回值true(或布尔结果为true的值)。单个赋值是不够的,因为可能的索引为0(布尔值(0)=== false),这不会导致错误但会禁用迭代的中断。
修改
上述更短的版本:
yourArray.some(function (elem, i) {
return elem.prop2 === 'yutu' && ~(index = i);
});
答案 4 :(得分:10)
var CarId = 23;
//x.VehicleId property to match in the object array
var carIndex = CarsList.map(function (x) { return x.VehicleId; }).indexOf(CarId);
答案 5 :(得分:3)
您可以通过以下方式使用Array.prototype.some()(如其他答案中所述):
https://jsfiddle.net/h1d69exj/2/
function findIndexInData(data, property, value) {
var result = -1;
data.some(function (item, i) {
if (item[property] === value) {
result = i;
return true;
}
});
return result;
}
var data = [{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"}]
alert(findIndexInData(data, 'prop2', "yutu")); // shows index of 1
答案 6 :(得分:1)
为什么你不想完全迭代?新的Array.prototype.forEach非常适用于此目的!
如果需要,您可以使用二进制搜索树通过单个方法调用查找。这是JS中的BTree和Red black搜索树的一个简洁实现 - https://github.com/vadimg/js_bintrees - 但我不确定你是否可以同时找到索引。
答案 7 :(得分:1)
function findIndexByKeyValue(_array, key, value) {
for (var i = 0; i < _array.length; i++) {
if (_array[i][key] == value) {
return i;
}
}
return -1;
}
var a = [
{prop1:"abc",prop2:"qwe"},
{prop1:"bnmb",prop2:"yutu"},
{prop1:"zxvz",prop2:"qwrq"}];
var index = findIndexByKeyValue(a, 'prop2', 'yutu');
console.log(index);
答案 8 :(得分:1)
我在上面已经看到了很多解决方案。
这里我使用map函数来查找数组对象中搜索文本的索引。
我将使用学生数据来解释我的答案。
第1步:为学生创建数组对象(可选您可以创建自己的数组对象)。
var students = [{name:"Rambabu",htno:"1245"},{name:"Divya",htno:"1246"},{name:"poojitha",htno:"1247"},{name:"magitha",htno:"1248"}];
第2步:创建变量以搜索文字
var studentNameToSearch = "Divya";
第3步:创建变量来存储匹配的索引(这里我们使用map函数进行迭代)。
var matchedIndex = students.map(function (obj) { return obj.name; }).indexOf(studentNameToSearch);
var students = [{name:"Rambabu",htno:"1245"},{name:"Divya",htno:"1246"},{name:"poojitha",htno:"1247"},{name:"magitha",htno:"1248"}];
var studentNameToSearch = "Divya";
var matchedIndex = students.map(function (obj) { return obj.name; }).indexOf(studentNameToSearch);
console.log(matchedIndex);
alert("Your search name index in array is:"+matchedIndex)
&#13;
答案 9 :(得分:0)
var list = [
{prop1:"abc",prop2:"qwe"},
{prop1:"bnmb",prop2:"yutu"},
{prop1:"zxvz",prop2:"qwrq"}
];
var findProp = p => {
var index = -1;
$.each(list, (i, o) => {
if(o.prop2 == p) {
index = i;
return false; // break
}
});
return index; // -1 == not found, else == index
}
答案 10 :(得分:0)
优化代码:
var index;
yourArray.some(function(entry, i) {
index = i;
return entry.prop2 == "yutu";
});
为什么他们所有人都回归真假。
答案 11 :(得分:0)
Georg已经提到过ES6有这个的Array.findIndex。 其他一些答案是ES5使用Array.some方法的解决方法。
一种更优雅的方法可以是
var index;
for(index = yourArray.length; index-- > 0 && yourArray[index].prop2 !== "yutu";);
同时我想强调一下,Array.some可以用二进制或其他有效的搜索技术实现。因此,在某些浏览器中,它可能比for循环更好。
答案 12 :(得分:0)
尝试此代码
var x = [{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"}]
let index = x.findIndex(x => x.prop1 === 'zxvz')
答案 13 :(得分:0)
另一种简单的方法是:
graphics.DrawImage(image, destRect, 0, 0, destRect.Width, destRect.Height, GraphicsUnit.Pixel, wrapMode);
答案 14 :(得分:0)
简单的一行:
apt