466

我有一个这样的数组:

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

如何在不遍历整个数组的情况下获取与条件匹配的对象的索引?

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

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

4

15 回答 15

1029

截至 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);

它在 Google 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');

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

于 2013-04-14T10:22:18.187 回答
31

如何获得与条件匹配的对象的索引(无需遍历数组)?

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

如果条件变化很大,那么您将不得不循环并查看其中的对象以查看它们是否符合条件。然而,在一个具有 ES5 特性的系统上(或者如果你安装了一个 shim),这个迭代可以相当简洁地完成:

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

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

或者当然,只使用一个for循环。您的各种迭代选项包含在其他答案中。

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

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

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

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

var entry = prop2map["yutu"];

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

于 2013-04-14T10:10:20.290 回答
26

TJ Crowder 所说的,每个地方都会有某种隐藏的迭代,用lodash这变成:

var index = _.findIndex(array, {prop2: 'yutu'})
于 2015-02-03T13:44:02.173 回答
18
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。

于 2017-08-16T23:35:35.177 回答
13
var index;
yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' ? (index = i, true) : false;
});

遍历数组的所有元素。如果条件不匹配,则返回索引和真或假。

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

编辑

上述更短的版本:

yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' && ~(index = i);
});
于 2015-04-08T17:50:23.950 回答
7

使用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);

于 2021-10-26T21:53:51.413 回答
5

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

在这里,我使用 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)

于 2018-02-12T10:19:44.200 回答
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
于 2015-03-19T21:51:54.583 回答
3
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);
于 2017-03-01T06:14:58.000 回答
2

试试这个代码

var x = [{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"}]
let index = x.findIndex(x => x.prop1 === 'zxvz')
于 2020-02-18T11:49:59.210 回答
1

Georg 已经提到 ES6 有 Array.findIndex 。其他一些答案是使用 Array.some 方法的 ES5 的解决方法。

一种更优雅的方法是

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

同时我想强调,Array.some 可以用二进制或其他有效的搜索技术来实现。因此,在某些浏览器中,它可能比 for 循环表现更好。

于 2017-07-26T11:03:35.163 回答
1

另一种简单的方法是:

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

const myIndex = getIndex(myArray);
于 2020-12-15T15:08:59.137 回答
0

为什么你不想精确地迭代?新的Array.prototype.forEach非常适合这个目的!

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

于 2013-04-14T10:18:10.990 回答
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
}
于 2017-01-20T18:04:08.360 回答
0

使用 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);

null如果未找到索引,将返回。

于 2016-12-05T14:12:24.433 回答