Javascript 如何只循环一次所有可能的JSON对象键对?

Javascript 如何只循环一次所有可能的JSON对象键对?,javascript,json,loops,object,Javascript,Json,Loops,Object,假设我有一个由n个元素组成的数据结构和一个函数check(element1,element2),它对两个元素执行某种检查。我需要检查所有可能的元素对。使用组合数学很容易推断出我们需要精确地执行“n选择2”二项式系数迭代(n*(n-1)/2迭代) 因此,如果我的数据结构是数组,则以下嵌套循环将起作用: for(let i = 0; i < elements.length; i++) { for(let j = i + 1; j < elements.length; j++) {

假设我有一个由n个元素组成的数据结构和一个函数
check(element1,element2)
,它对两个元素执行某种检查。我需要检查所有可能的元素对。使用组合数学很容易推断出我们需要精确地执行“n选择2”二项式系数迭代(
n*(n-1)/2
迭代)

因此,如果我的数据结构是数组,则以下嵌套循环将起作用:

for(let i = 0; i < elements.length; i++) {
    for(let j = i + 1; j < elements.length; j++) {
        check(elements[i], elements[j]);
    }
}
然而,很明显,我们不止一次地进行了大量检查,结果是n^2次迭代


我可以使用什么方法获得与数组示例中相同的结果?

也许您可以获得数组中的键列表:

let elements = { a: 1, b: 2, c: 3 };
let keys = Object.keys(elements).sort(); // Sorts the keys array alphabetically, and thus simulating the numbers example and be sure you're not repeating "lower" order key after passing it
for(let i = 0; i < keys.length; i++) {
    for(let j = i + 1; j < keys.length; j++) {
        // check(elements[keys[i]], elements[keys[j]]);
        console.log(elements[keys[i]], elements[keys[j]])
    }
}

如果使用
Object.keys()
将要循环的所有键放入一个数组中,则可以使用标准for循环“跳过”以前看到的键,如下所示:

const keys = Object.keys(elements);
for(let i = 0; i < keys.length; i++) {
  const key1 = keys[i]; 
  for(let j = i + 1; j < keys.length; j++) {
    const key2 = keys[j];
    check(elements[key1], elements[key2]);
  }
}
const keys=Object.keys(元素);
for(设i=0;i
如果不是字符串,则不是。不应
检查(元素[key1],元素[key1])be
检查(元素[key1],元素[key2])(注意
键2
)正确;修正了这个问题在你的例子中,“键”是按字母顺序排序的,这与整数是按从低到高的顺序排序的,所以你可以确保你没有两次碰到同一个键。但在大多数情况下,它们不会被分类。你可以做的,只是在迭代数组之前简单地键入关键字:)我会编辑你的答案来反映/我确实考虑了这样的解决方案,但是我对低级JavaScript一点都不熟悉,这让我想知道:这个方法到底有多有效?特别是在处理大量元素时,分配一个长度相同的全新数组比迭代大约两倍的数组更可行吗?@user10433783这是一个内存效率与计算效率的问题。好吧,分配一个全新数组的效率应该会低一些,但我不能确定。@user10433783在计算键方面,大约需要
O(n)
其中
n
是元素对象中的键数。这只需在循环之外执行一次,因此对于大型数据集,我们的计算时间复杂性仍然是O(n^2)。但是,总的来说,我认为在查看大量数据时可以节省时间,因为您的内部循环不需要每次运行
n
次(特别是在接近循环结束时,与
n
次相比,它可能只需运行1到2次)。如果您关心空间效率,那么您最初的方法会更好
1 2
1 3
2 3
const keys = Object.keys(elements);
for(let i = 0; i < keys.length; i++) {
  const key1 = keys[i]; 
  for(let j = i + 1; j < keys.length; j++) {
    const key2 = keys[j];
    check(elements[key1], elements[key2]);
  }
}