[英]How can I iterate over all unique pairs of entries in an object?
I currently have an array data structure that I iterate over like this, calling foo
on each unique pair of elements. 我目前有一个数组数据结构,我迭代这样,在每个独特的元素对上调用
foo
。
for(var i = 0; i < arr.length; i++) {
for(var j = i + 1; j < arr.length; j++) {
foo(arr[i], arr[j]);
}
}
However, I've realized that I'd rather use an object instead of an array, since I can then add and remove elements by name very easily. 但是,我意识到我宁愿使用一个对象而不是一个数组,因为我可以很容易地按名称添加和删除元素。
However, I can't see an obvious way to iterate over such an object. 但是,我看不到一种明显的方法来迭代这样的对象。 The closest I can get is:
我能得到的最接近的是:
for(i in obj) {
for(j in obj) {
foo(obj[i], obj[j]);
}
}
Obviously, this will do each pair twice, and even produce a pair of identical elements. 显然,这将每对做两次,甚至产生一对相同的元素。 Is there an easy way to iterate over an object in the same way as I do in the array in my first code sample?
是否有一种简单的方法来迭代对象,就像我在第一个代码示例中的数组中一样?
Performance testing the solutions on jsperf . 在jsperf上测试解决方案的性能。
My solution that was at first written as a comment: 我的解决方案最初是作为评论写的:
Add an if (i < j)
condition in the inner loop. 在内循环中添加
if (i < j)
条件。 It might not be the best solution, but it would work as long as the foo function does the same thing for foo(2, 10)
and foo(10, 2)
: 它可能不是最好的解决方案,但只要foo函数对
foo(2, 10)
foo(10, 2)
foo(2, 10)
和foo(10, 2)
foo(2, 10)
执行相同的操作,它就会起作用:
for(i in obj) {
for(j in obj) {
if (i < j) {
foo(obj[i], obj[j]);
}
}
}
Assuming I understand your question... maybe check to see if the value has already been visited by the outer loop? 假设我理解你的问题...也许检查一下外循环是否已经访问过该值?
var visited = {}
for(i in obj) {
visited[i] = true;
for(j in obj) {
if(j in visited){ continue; }
foo(obj[i], obj[j]);
}
}
Use Object.keys() to get the list of keys out as an array: 使用Object.keys()以数组的形式获取键列表:
keys = Object.keys();
for(i=0;i<keys.length;i++) {
for(j=i+1;j<keys.length;j++) {
foo(obj[keys[i]], obj[keys[j]]);
}
}
Maybe You can try unset used objects: 也许您可以尝试取消设置未使用的对象:
for(i in obj) {
var a = obj[i];
delete obj[i];
for(j in obj) {
foo(a, obj[j]);
}
}
http://jsfiddle.net/bXcvb/ http://jsfiddle.net/bXcvb/
If you need to original obj in tact see: How do I correctly clone a JavaScript object? 如果您需要原始obj,请参阅: 如何正确克隆JavaScript对象?
You can push the object keys into an array: 您可以将对象键推送到数组中:
var obj_keys = [];
for (i in obj) {
obj_keys.push(i);
}
for(i = 0; i < obj_keys.length; ++i) {
for(j = i + 1; j < obj_keys.length; ++j) {
foo(obj[obj_keys[i]], obj[obj_keys[j]]);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.