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

Currently, I have an array data structure that I repeat like this, invoking foofor 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 realized that it is better to use an object instead of an array, since I can easily add and remove elements by name.

However, I do not 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 create a pair of identical elements. Is there an easy way to iterate over an object in the same way as I do in an array in my first code example?

Update:

Checking the performance of solutions on jsperf .

+3
source share
5

, :

if (i < j) . , , foo foo(2, 10) foo(10, 2):

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

, ... , , ?

var visited = {}
for(i in obj) {
    visited[i] = true;
    for(j in obj) {
        if(j in visited){ continue; }
        foo(obj[i], obj[j]);
    }
}
+2

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

, :

for(i in obj) {
    var a = obj[i];
    delete obj[i];
    for(j in obj) {
        foo(a, obj[j]);
    }
}

http://jsfiddle.net/bXcvb/

obj , . JavaScript?

+2

:

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

All Articles