获取匹配条件的数组中对象的索引

我有一个这样的数组:

[{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"},...]

我怎么能得到对象的索引,匹配的条件,而不是在整个数组上迭代?

例如,给定prop2=="yutu",我想获取索引1

我看到.indexOf(),但认为它用于简单的数组,如["a1","a2",...]。我还检查了$.grep(),但返回的是对象,而不是索引。

715314 次浏览

我怎么能得到对象的索引匹配的条件(没有迭代沿数组)?

你不能,某物必须遍历数组(至少一次)。

如果条件变化很大,则必须遍历并查看其中的对象,以确定它们是否与条件匹配。然而,在一个带有ES5特性的系统上(或者如果你安装了一个shim),这个迭代可以相当简单地完成:

var index;
yourArray.some(function(entry, i) {
if (entry.prop2 == "yutu") {
index = i;
return true;
}
});

它使用了新的(ish) Array#some函数,循环遍历数组中的条目,直到你给它的函数返回true。我给它的函数保存匹配条目的索引,然后返回true以停止迭代。

当然,也可以使用for循环。你的各种迭代选项包含在另一个答案中。

但如果你总是要使用相同的属性进行查找,如果属性值是唯一的,你可以只循环一次,并创建一个对象来映射它们:

var prop2map = {};
yourArray.forEach(function(entry) {
prop2map[entry.prop2] = entry;
});

(或者,同样,你可以使用for循环或任何你的其他选择循环。)

然后,如果你需要找到带有prop2 = "yutu"的条目,你可以这样做:

var entry = prop2map["yutu"];

我称之为“交叉索引”数组。当然,如果你删除或添加条目(或改变它们的prop2值),你也需要更新你的映射对象。

为什么不进行迭代呢?新的Array.prototype.forEach非常适合这个目的!

如果需要,可以使用二叉搜索树通过单个方法调用进行查找。这是一个整洁的实现的BTree和红黑搜索树在JS - https://github.com/vadimg/js_bintrees -但我不确定你是否能同时找到索引。

截至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。对于ie浏览器,在链接页面上有一个填充。

性能报告

函数调用是非常昂贵的,因此对于非常大的数组,简单的循环将比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');

与大多数优化一样,这应该在实际需要时谨慎应用。

TJ Crowder说,每个方法都会有某种隐藏迭代,使用lodash这就变成:

var index = _.findIndex(array, {prop2: 'yutu'})

你可以以以下方式使用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
var index;
yourArray.some(function (elem, i) {
return elem.prop2 === 'yutu' ? (index = i, true) : false;
});
遍历数组的所有元素。 如果条件不匹配,则返回索引值和true或false

重要的是显式返回值为true(或布尔结果为true的值)。单个赋值是不够的,因为索引可能为0 (Boolean(0) === false),这不会导致错误,但会禁用中断迭代。

编辑

上面的一个更简短的版本:

yourArray.some(function (elem, i) {
return elem.prop2 === 'yutu' && ~(index = i);
});

使用Array.reduce()的一个步骤-没有jQuery

var items = [{id: 331}, {id: 220}, {id: 872}];


var searchIndexForId = 220;
var index = items.reduce(function(searchIndex, item, index){
if(item.id === searchIndexForId) {
console.log('found!');
searchIndex = index;
}
return searchIndex;
}, null);

如果没有找到index,将返回null

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

Georg已经提到了ES6有数组。查找索引。 其他一些答案是ES5使用Array的变通方法。一些方法。< / p >

一种更优雅的方法是

var index;
for(index = yourArray.length; index-- > 0 && yourArray[index].prop2 !== "yutu";);

同时,我想强调一下,阵列。有些可以用二进制或其他有效的搜索技术实现。因此,在某些浏览器中,它可能在for循环中执行得更好。

var CarId = 23;


//x.VehicleId property to match in the object array
var carIndex = CarsList.map(function (x) { return x.VehicleId; }).indexOf(CarId);

对于基本数组号,你也可以这样做:

var numberList = [100,200,300,400,500];
var index = numberList.indexOf(200); // 1

如果它在数组中找不到值,就会得到-1。

我在上面看到了很多解决方案。

在这里,我使用map函数在数组对象中查找搜索文本的索引。

我将用学生数据来解释我的答案。

  • 步骤1:为学生创建数组对象(可选,您可以创建自己的数组对象) 李var students = [{name:"Rambabu",htno:"1245"},{name:"Divya",htno:"1246"},{name:"poojitha",htno:"1247"},{name:"magitha",htno:"1248"}]; < / p > < / >

  • 步骤2:创建变量搜索文本
    var studentNameToSearch = "Divya"; < / p > < / >

  • 步骤3:创建变量存储匹配的索引(这里我们使用map函数进行迭代) 李var matchedIndex = students.map(function (obj) { return obj.name; }).indexOf(studentNameToSearch); < / p > < / >

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)

试试这段代码

var x = [{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"}]
let index = x.findIndex(x => x.prop1 === 'zxvz')

另一种简单的方法是:

 function getIndex(items) {
for (const [index, item] of items.entries()) {
if (item.prop2 === 'yutu') {
return index;
}
}
}


const myIndex = getIndex(myArray);

使用Array.map()Array.indexOf(string)

const arr = [{
prop1: "abc",
prop2: "qwe"
}, {
prop1: "bnmb",
prop2: "yutu"
}, {
prop1: "zxvz",
prop2: "qwrq"
}]


const index = arr.map(i => i.prop2).indexOf("yutu");


console.log(index);

最好的&最快的方法是:

const products = [
{ prop1: 'telephone', prop2: 996 },
{ prop1: 'computadora', prop2: 1999 },
{ prop1: 'bicicleta', prop2: 995 },
];


const index = products.findIndex(el => el.prop2 > 1000);


console.log(index); // 1