How can I iterate over all unique pairs of entries in an object?

大城市里の小女人 提交于 2019-12-10 16:58:56

问题


I currently have an array data structure that I iterate over like this, calling foo on each unique pair of elements.

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?

Update:

Performance testing the solutions on jsperf.


回答1:


My solution that was at first written as a comment:

Add an if (i < j) condition in the inner loop. 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):

for(i in obj) {
    for(j in obj) {
        if (i < j) {
            foo(obj[i], obj[j]);
        }
    }
}



回答2:


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



回答3:


Use Object.keys() to get the list of keys out as an array:

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



回答4:


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/

If you need to original obj in tact see: How do I correctly clone a JavaScript object?




回答5:


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


来源:https://stackoverflow.com/questions/10505286/how-can-i-iterate-over-all-unique-pairs-of-entries-in-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!