【问题标题】:How to loop through all possible pairs of JSON object keys exactly once?如何只循环一次所有可能的 JSON 对象键对?
【发布时间】:2020-01-06 08:26:51
【问题描述】:

假设我有一个包含 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]);
    }
}

这样,我们检查第一个元素和所有其他元素,第二个元素检查元素 3 到 n(因为我们已经检查了第一个元素),第三个元素检查元素 4 到 n,依此类推。但是,如果“元素”是一个 JSON,其中每个元素的键不是整数,我们如何实现这种效果?显然,我们可以确保使用以下代码执行所有检查:

for(var key1 in elements) {
    for(var key2 in elements) {
        if(key1 != key2) {
            check(elements[key1], elements[key2]);
        }
    }
}

但显然我们不止一次地进行了大量检查,导致 n^2 次迭代。

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

【问题讨论】:

标签: javascript json loops object


【解决方案1】:

也许你可以得到一个数组中的键列表:

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

输出:

1 2
1 3
2 3

【讨论】:

  • 在您的示例中,“键”按字母顺序排序,这与整数从低到高排序相同,因此您可以确保您没有按两次相同的键。但在大多数情况下,它们不会被排序。你可以做的,只是在遍历数组之前对键进行排序:) 我会编辑你的答案以反映这一点/
【解决方案2】:

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

【讨论】:

  • 我确实考虑过这样的解决方案,但是我对低级 javascript 一点也不熟悉,这让我想知道:这种方法到底有多高效?尤其是在处理大量元素时,与大约两倍的迭代相比,分配一个相同长度的全新数组更可行吗?
  • @user10433783 这是一个内存效率与计算效率的问题。 afaik,分配一个全新的数组应该效率较低,但我不能确定。
  • @user10433783 在计算键方面,大约需要O(n),其中n 是元素对象中的键数。这仅在循环之外执行一次,因此对于大量数据集,您的计算时间复杂度仍将是 O(n^2)。但是,总的来说,我会说它会在查看大量数据时节省时间,因为您的内部循环不需要每次运行 n 次(尤其是在循环结束时它可能必须运行 1或与n 次相比仅两倍)。如果您关心空间效率,那么您的原始方法会更好
猜你喜欢
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 2020-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多