我如何可以遍历条目的所有唯一对的对象?(How can I iterate over all uni

2019-09-17 02:33发布

我现在有我遍历一个这样的阵列,主叫foo每个唯一的一对元件。

for(var i = 0; i < arr.length; i++) {
    for(var j = i + 1; j < arr.length; j++) {
        foo(arr[i], arr[j]);
    }
}

不过,我意识到,我宁愿使用一个对象而不是数组的,因为我可以再由名字很容易添加和删除元素。

不过,我看不到一个明显的方式来遍历这样一个对象。 我能得到的最接近的是:

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

显然,这将做每对两次,甚至产生一对相同的元件。 有没有一种简单的方法,我在数组中我第一个代码示例在做遍历对象以同样的方式?

更新:

性能测试的解决方案jsperf 。

Answer 1:

我的解决方案,在第一次写的评论:

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


Answer 2:

假设我明白你的问题......也许检查,看看是否值已经由外环访问?

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


Answer 3:

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


Answer 4:

也许你可以尝试取消设置使用的对象:

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对象?



Answer 5:

你可以把对象键到一个数组:

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


文章来源: How can I iterate over all unique pairs of entries in an object?