Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对象数组中的indexOf方法?_Javascript - Fatal编程技术网

Javascript 对象数组中的indexOf方法?

Javascript 对象数组中的indexOf方法?,javascript,Javascript,获取包含对象的数组索引的最佳方法是什么 想象一下这个场景: var hello = { hello: 'world', foo: 'bar' }; var qaz = { hello: 'stevie', foo: 'baz' } var myArray = []; myArray.push(hello,qaz); 现在我想得到对象的索引,hello属性是'stevie',在这个例子中,它是1 我是JavaScript的新手,我不知道是否有一个简单的方法,或者

获取包含对象的数组索引的最佳方法是什么

想象一下这个场景:

var hello = {
    hello: 'world',
    foo: 'bar'
};
var qaz = {
    hello: 'stevie',
    foo: 'baz'
}

var myArray = [];
myArray.push(hello,qaz);
现在我想得到对象的索引,hello属性是'stevie',在这个例子中,它是1

我是JavaScript的新手,我不知道是否有一个简单的方法,或者我是否应该构建自己的函数来实现这一点。

在除IE non edge之外的所有浏览器中都受支持。但是提供的服务很好

var idx = myArray.reduce( function( cur, val, index ){

    if( val.hello === "stevie" && cur === -1 ) {
        return index;
    }
    return cur;

}, -1 );
var indexOfStevie = myArray.findIndex(i => i.hello === "stevie");
使用map的解决方案是可以的。但每次搜索时,您都会对整个数组进行迭代。这只是findIndex最糟糕的情况,一旦找到匹配项,findIndex就会停止迭代

当开发人员不得不担心IE8时,并没有一种简洁的方法,但这里有一个常见的解决方案:

var searchTerm = "stevie",
    index = -1;
for(var i = 0, len = myArray.length; i < len; i++) {
    if (myArray[i].hello === searchTerm) {
        index = i;
        break;
    }
}
请参见此示例:

它开始以零开始计数。

或者:


我认为您可以使用以下函数在一行中求解:

function arrayObjectIndexOf(myArray, searchTerm, property) {
    for(var i = 0, len = myArray.length; i < len; i++) {
        if (myArray[i][property] === searchTerm) return i;
    }
    return -1;
}
arrayObjectIndexOf(arr, "stevie", "hello"); // 1
pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');

我喜欢Pablo的答案,但是ArrayindexOf和Arraymap并不是在所有浏览器上都能工作。下划线将使用本机代码(如果可用),但也有回退。此外,它还提供了Pulk方法,可以完全实现Pablo的匿名映射方法的功能

var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();
我更喜欢使用findIndex方法:


index将为您提供索引编号。

您可以创建自己的原型来执行此操作:

比如:

Array.prototype.indexOfObject = function (object) {
    for (var i = 0; i < this.length; i++) {
        if (JSON.stringify(this[i]) === JSON.stringify(object))
            return i;
    }
}
注意[0]

在安东尼奥·拉古纳的回答中使用reduce是恰当的


抱歉这么简单…

我制作了一个通用函数来检查下面的代码是否适用于任何对象

function indexOfExt(list, item) {
    var len = list.length;

    for (var i = 0; i < len; i++) {
        var keys = Object.keys(list[i]);
        var flg = true;
        for (var j = 0; j < keys.length; j++) {
            var value = list[i][keys[j]];
            if (item[keys[j]] !== value) {
                flg = false;
            }
        }
        if (flg == true) {
            return i;
        }
    }
    return -1;
}

var items = [{ "hello": 'world', "foo": 'bar' }];
var selectedItem = { "hello": 'world', "foo": 'bar' };
alert(items.indexOf(selectedItem));
alert(indexOfExt(items, selectedItem));
第一个警报将返回-1表示未找到匹配项,第二个警报将返回0表示找到匹配项。

Brief 用例: 应用程序编程接口:
这是在数组中查找对象索引的方法

    var myArray = [{  hello: 'world',
        foo: 'bar'
    },{
        hello: 'stevie',
        foo: 'baz'
    }];



    for (i = 0; i < myArray.length; i++) {
        if (myArray[i].hello === 'stevie') {
            alert('position: ' + i);
            return;
        }
    }
使用u.findIndex from

下面是一个例子
_.findIndex[{a:1},{a:2,c:10},{a:3}],{a:2,c:10}//1

这在没有自定义代码的情况下工作

var arr, a, found;
arr = [{x: 1, y: 2}];
a = {x: 1, y: 2};
found = JSON.stringify(arr).indexOf(JSON.stringify(a)) > - 1;
// found === true
注意:这并没有给出实际的索引,它只告诉您的对象是否存在于当前的数据结构中

使用ES6,不使用lodash或任何其他库,您可以编写:

function deepIndexOf(arr, obj) {
  return arr.findIndex(function (cur) {
    return Object.keys(obj).every(function (key) {
      return obj[key] === cur[key];
    });
  });
}
这将比较对象的直接属性,但不会递归到属性中

如果您的实现没有提供findIndex,但大多数都没有,则可以添加支持此搜索的轻型多边形填充:

function deepIndexOf(arr, obj) {
  function findIndex = Array.prototype.findIndex || function (pred) {
    for (let i = 0; i < this.length; ++i) {
      if (pred.call(this, this[i], i)) {
        return i;
      }
    }

    return -1;
  }

  return findIndex.call(arr, function (cur) {
    return Object.keys(obj).every(function (key) {
      return obj[key] === cur[key];
    });
  });
}
根据我在

上的回答,您可以使用适用于不受支持的浏览器的

我看到人们否决了这个答案,我希望他们这样做是因为语法错误,因为在我看来,这是最优雅的方式

如果数组中的元素满足提供的测试函数,findIndex方法将返回数组中的索引。否则返回-1

例如:

var hello={ 您好:'世界', 福:“酒吧” }; 变量qaz={ 你好:'史蒂夫', 福:“巴兹” } var myArray=[]; myArray.pushhello,qaz; var index=myArray.findIndexfunctionelement{ return element.hello=='stevie'; }; 警报指数 试试这个:

console.log(Object.keys({foo:"_0_", bar:"_1_"}).indexOf("bar"));
简单:

myArray.indexOf(myArray.filter(function(item) {
    return item.hello == "stevie"
})[0])

您可以使用本机且方便的函数Array.prototype.findIndex,基本上:

如果数组中的元素满足提供的测试函数,findIndex方法将返回数组中的索引。否则返回-1

请注意,Internet Explorer、Opera和Safari不支持此功能,但您可以使用下面链接中提供的Polyfill

更多信息:

var hello={ 您好:'世界', 福:“酒吧” }; 变量qaz={ 你好:'史蒂夫', 福:“巴兹” } var myArray=[]; myArray.pushhello,qaz; var index=myArray.findIndexfunctionelement,索引,数组{ if element.hello==='stevie'{ 返回true; } }; 警报“stevie在索引处:”+索引 你可以简单地使用

常数someId=2; 常量数组=[{id:1},{id:2},{id:3}]; const index=array.reducei,item,index=>item.id==someId?指数:i,-1;
警报“someId”+someId+”位于索引“+index”处 在ES2015中,这非常简单:

myArray.map(x => x.hello).indexOf('stevie')
或者,对于较大的阵列,可能具有更好的性能:

myArray.findIndex(x => x.hello === 'stevie')

如果你只对找到这个职位感兴趣,请参阅

pos=myArray.mapfunctione{returne e.hello;}.indexOf'stevie'

但是,如果您希望找到元素,也就是说,如果您想做类似于myArray[pos]的事情,那么有一种更有效的单行方法,使用filter

element=myArray.filtere=>e.hello===='stevie'[0]

参见性能结果~+42%运行/秒:

我在这里对各种答案进行了性能测试,任何人都可以自己运行:

根据我在Chrome中的初始测试,以下使用在原型中设置for循环的方法是最快的:

Array.prototype.indexOfObject = function (property, value) {
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i][property] === value) return i;
    }
    return -1;
}

myArray.indexOfObject("hello", "stevie");

如果您的对象与您在数组中使用的对象是同一个对象,那么您应该能够像获取字符串一样获取对象的索引

var hello = {
    hello: 'world',
    foo: 'bar'
};
var qaz = {
    hello: 'stevie',
    foo: 'baz'
}

var qazCLONE = { // new object instance and same structure
    hello: 'stevie',
    foo: 'baz'
}

var myArray = [hello,qaz];

myArray.indexOf(qaz) // should return 1
myArray.indexOf(qazCLONE) // should return -1

我比较了几种方法,得到了解决这个问题最快的方法。这是给我的 哎呀。它比任何其他方法快5倍以上


这是测试页面:

然而,这里的大多数其他答案都是有效的。有时候,最好在您将要使用的位置附近制作一个简短的函数

// indexOf wrapper for the list of objects
function indexOfbyKey(obj_list, key, value) {
    for (index in obj_list) {
        if (obj_list[index][key] === value) return index;
    }
    return -1;
}
// Find the string in the list (default -1)
var test1 = indexOfbyKey(object_list, 'name', 'Stevie');
var test2 = indexOfbyKey(object_list, 'last_name', 'some other name');

这取决于什么对你重要。它可以节省代码行数,并且非常聪明地使用一行代码,或者将一个通用的解决方案放在涵盖各种边缘情况的地方。但有时最好只是说:在这里,我是这样做的,而不是让未来的开发人员从事额外的逆向工程工作。特别是如果你认为自己是一个新手。p> 这里的大多数回答并不能解决所有问题。 我发现这个解决方案更好:

const isInarray=myArr.filterobj=>obj.hello==='stevie'和&obj.foo==='baz'。长度>0; 如果伊西纳雷{ .... }

你想合并hello和qaz这两个对象吗?不想。我想要一个数组中的对象列表。啊,好的!您想知道整个对象在数组中的位置,它有一个已定义的属性。我找到了一个非常简单的函数来解决这个问题,答案如下:var elementPos=array.mapfunctionx{return x.id;}.indexofidyouraeloking;var objectFound=array[elementPos];[link]如果ES6适合您,ES6 Array.indexOf优于公认的答案-请参阅下面的完整示例该函数的searchterm比较错误,因为它应该是searchterm:存在多个occurences@SteveBennett这是一个性能优化的版本;当for循环的变量初始化时,数组的长度只需确定一次。在您的情况下,每次迭代都会重新检查长度。但是,如果性能不是很高,这并不重要。答案很好,但我做了一些性能基准测试,发现这里提到的基于函数的答案似乎是第二高性能的答案。唯一更有效的方法是将其放入原型中,而不是如中所述的函数中。这应该是公认的答案。现在大多数浏览器都支持Array.prototype.mapIt,IE8不支持它,但如果这不是问题的话,这是最好的解决方案。嗯。。。Array.prototype.map创建了一个包含映射项的全新数组,这难道不值得注意吗?那么,如果你有一个包含1000个元素的数组,你首先创建了另一个包含1000个元素的数组,然后搜索它?我认为值得一看这种方法与简单for循环的性能。特别是当你在资源有限的移动平台上运行时。@Doug虽然你关于性能的观点确实正确,在他们分析瓶颈之前,对于一个几乎被定义为IO/网络绑定的应用程序,谁会用七行代码替换一行代码呢;非常方便!虽然我会选择prototype.indexOfObject,以免干扰现有的Array.indexOf方法。Array.prototype.indexOfObject=functionproperty,值{for var i=0,len=this.length;i可怜的是,它似乎会做同样的事情,但最终还是表现不佳?请参阅我答案中的链接了解基准测试。很高兴知道性能对于手头的任务是否重要。根据我的经验,它很少是,但是ymmv。这个方法看起来很优雅,但是根据MDN没有IE支持?试着在答案中使用polyfill链接。使用数组某种方法。我正要用我自己的测试来发布这个问题的答案,但多亏了你的回答,我不必再这样做了。我只是想确认一下你的测试——我得到了相同的结果,但是使用了while循环而不是for one,并且性能良好。我希望这个答案能得到更多的支持,并且我能更早地看到它,这会节省我一些时间…错过一个循环不?太糟糕了,人们不会向下滚动两个答案。这是唯一的好答案。谢谢。这是我一直在寻找的答案,因为我不清楚IndexOf是否与值匹配。现在我知道我可以使用IndexOf来查找我的对象,而不用担心是否有其他具有相同属性的对象。
function deepIndexOf(arr, obj) {
  function findIndex = Array.prototype.findIndex || function (pred) {
    for (let i = 0; i < this.length; ++i) {
      if (pred.call(this, this[i], i)) {
        return i;
      }
    }

    return -1;
  }

  return findIndex.call(arr, function (cur) {
    return Object.keys(obj).every(function (key) {
      return obj[key] === cur[key];
    });
  });
}
console.log(Object.keys({foo:"_0_", bar:"_1_"}).indexOf("bar"));
myArray.indexOf(myArray.filter(function(item) {
    return item.hello == "stevie"
})[0])
myArray.map(x => x.hello).indexOf('stevie')
myArray.findIndex(x => x.hello === 'stevie')
Array.prototype.indexOfObject = function (property, value) {
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i][property] === value) return i;
    }
    return -1;
}

myArray.indexOfObject("hello", "stevie");
myArray.indexOfObject("hello", "stevie");
var hello = {hello: "world",  foo: "bar"};
var qaz = {hello: "stevie", foo: "baz"};
var myArray = [];
myArray.push(hello,qaz);

function indexOfObject( arr, key, value   ) {
    var j = -1;
    var result = arr.some(function(obj, i) { 
        j++;
        return obj[key] == value;
    })

    if (!result) {
        return -1;
    } else {
        return j;
    };
}

alert(indexOfObject(myArray,"hello","world"));
var hello = {
    hello: 'world',
    foo: 'bar'
};
var qaz = {
    hello: 'stevie',
    foo: 'baz'
}

var qazCLONE = { // new object instance and same structure
    hello: 'stevie',
    foo: 'baz'
}

var myArray = [hello,qaz];

myArray.indexOf(qaz) // should return 1
myArray.indexOf(qazCLONE) // should return -1
// indexOf wrapper for the list of objects
function indexOfbyKey(obj_list, key, value) {
    for (index in obj_list) {
        if (obj_list[index][key] === value) return index;
    }
    return -1;
}
// Find the string in the list (default -1)
var test1 = indexOfbyKey(object_list, 'name', 'Stevie');
var test2 = indexOfbyKey(object_list, 'last_name', 'some other name');