【问题标题】:Best way to find index of exact same object in object Array (key is dynamic)在对象数组中查找完全相同对象的索引的最佳方法(键是动态的)
【发布时间】:2017-01-05 09:37:00
【问题描述】:

假设我每次都动态加载具有不同属性和该类型对象数组的对象:

var obj = {name: someValue, key: someValue2};
var objArray = [{name: someValue, key: someValue2},{name: someValue, key: someValue3}];

我想找到包含 objobjArray 的索引。 objArray 的某些元素可以具有相同的 name 属性但不同的 key 属性,因此不能通过 obj.name 进行搜索一个选项。到目前为止,我想出了这个解决方案:

var keys = [];

_.forEach(Object.keys(obj), function(key) {
  keys.push(key, obj[key])
});

var index = _.findIndex(objArray, keys);

这很好用,但我正在寻找性能更好的东西,因为这个 objArray 可能非常大。

所以问题是:有没有更好的方法在对象数组中找到完全相同对象的索引?

更新: 我忘了提到键的名称没有指定,并且每次都可能不同。

【问题讨论】:

  • objectArray.indexOf(object) 能解决你的问题吗?
  • objectArray.indexOf(object) 似乎不起作用
  • @GirdhariAgrawal — indexOf(object) 不起作用...使用 Array#findIndex
  • 还是只使用对象作为键?

标签: javascript object lodash


【解决方案1】:

使用Array.prototype.findIndex(),这只有在您事先知道要检查的属性并在.findIndex() 的回调中硬编码规则时才有效。

一个例子:

var obj = {
  name: 'someValue',
  key: 'someValue3'
};
var objArray = [{
  name: 'someValue',
  key: 'someValue2'
}, {
  name: 'someValue',
  key: 'someValue3'
}];
var index = objArray.findIndex(function(item, index) {
  return (item.name === obj.name) && (item.key === obj.key) ? true : false;
});
console.log('index is: ' + index);

这是另一种方法,基本上它采用 JavaScript 值(您的初始对象)并转换为 JSON 字符串,并使用该字符串在您的数组中搜索。该脚本无需任何递归即可工作,具有任意数量的对象嵌套属性。您的属性的顺序在此脚本中很重要,因为转换为字符串时会考虑到它。

关于“最佳方式”很难回答,这取决于您的最佳方式参数是什么。如果您考虑性能,您应该考虑对脚本进行基准测试并使用一些真实数据进行测试。

var obj = {
  name: 'someValue',
  key: 'someValue2'
},
objArray = [{
  name: 'someValue',
  key: 'someValue2'
}, {
  name: 'someValue',
  key: 'someValue3'
}];

var str = JSON.stringify(obj),
    index = objArray.findIndex(function(item, index) {
  return str === JSON.stringify(item) ;
});
console.log('index is: ' + index);

【讨论】:

  • 这并不能解决我的问题,因为对象可以有不同的键名:不仅仅是'name'和'key'
  • @KonradKahl 感谢您的评论。我已对我的答案进行了编辑。
  • @KonradKahl 属性的顺序很重要吗?
  • 没有。顺序并不重要。
  • @KonradKahl 我进行了编辑,看看它是否符合您的要求。关于速度和性能,只有测试和基准测试才能让您清楚地知道什么是更快的方法。
【解决方案2】:

我可以想到两种方法:

1.) 加快这个过程(特别是如果你有大数组和大对象)是为每个对象创建某种唯一键并将其映射到假设属性称为:哈希。如果你想保持原样,最好的方法可能是使用 String.hashCode() 方法。

迭代槽对象 OWN(检查 hasOwnProperty)属性并将属性名称和 ### 以及值和 %%% 连接成单个字符串。

然后使用属性散列增强您的对象,例如:

myObj.hash = String.hashCode(StringOfNamesAndValues);

现在使用 for 遍历您的数组,并将 obj.hash 与 objArray[index].hash 进行比较

一旦他们匹配你喜欢你的对象,存储索引:)

如果您的对象和数组中的对象不必完全相同对象,但只有一个子集需要相同。而不是在哈希生成中使用所有属性名称,只使用您想要相同的属性的名称和值。比较以这种方式生成的哈希值 - 瞧!

2.) 更野蛮的方法是使对象相等的函数接受 2 个对象并比较各个属性的所有属性和值。 现在使用该函数迭代槽数组强>。将您的对象和数组对象作为参数传递。如果它返回该比较为真,则存储索引。

对象越大,运行速度越慢。数组越大,运行速度越慢。您搜索相同对象的时间越多,这工作的速度就越慢(您每次比较而不是进行一次哈希)。

另外,如果您有一个非常大的对象集,并且经常搜索但稀疏地添加或删除它,请考虑根据哈希值对数组进行排序。然后使用二叉树搜索该哈希来找到合适的对象,而不是每次从头到尾迭代。

【讨论】:

    猜你喜欢
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多