簡體   English   中英

如何在 JavaScript 中創建此對象的鍵/值的所有組合?

[英]How can I create all combinations of this object's keys/values in JavaScript?

我有以下 JavaScript 對象結構:

var options = {
    optionOne: [true, false],
    optionTwo: [true, false],
    optionThree: [
        null,
        {property1: 9, property2: 7},
        {property1: 4, property2: 12},
        {property1: 16, property2: 14}
    ]
};

請注意,此對象中的密鑰/對的數量會有所不同。 所以實際上可能有optionFouroptionFive等,並且每個選項的數組可以有任意數量或類型的值。

我需要遍歷這個對象並創建一個包含所有可能選項組合的對象的數組:

[
    {optionOne: true,  optionTwo, true,  optionThree: null},
    {optionOne: false, optionTwo, true,  optionThree: null},
    {optionOne: true,  optionTwo, false, optionThree: null},
    {optionOne: false, optionTwo, false, optionThree: null},
    {optionOne: true,  optionTwo, true,  optionThree: {property1: 9, property2: 7}},
    {optionOne: false, optionTwo, true,  optionThree: {property1: 9, property2: 7}},
    {optionOne: true,  optionTwo, false, optionThree: {property1: 9, property2: 7}},
    {optionOne: false, optionTwo, false, optionThree: {property1: 9, property2: 7}},
    {optionOne: true,  optionTwo, true,  optionThree: {property1: 4, property2: 12}},
    {optionOne: false, optionTwo, true,  optionThree: {property1: 4, property2: 12}},
    {optionOne: true,  optionTwo, false, optionThree: {property1: 4, property2: 12}},
    {optionOne: false, optionTwo, false, optionThree: {property1: 4, property2: 12}},
    {optionOne: true,  optionTwo, true,  optionThree: {property1: 16, property2: 14}},
    {optionOne: false, optionTwo, true,  optionThree: {property1: 16, property2: 14}},
    {optionOne: true,  optionTwo, false, optionThree: {property1: 16, property2: 14}},
    {optionOne: false, optionTwo, false, optionThree: {property1: 16, property2: 14}}
]

我正在努力解決這個問題,但我相當有信心答案在於遞歸。

算法大神能幫幫我嗎?

function getCombinations(options, optionIndex, results, current) {
    var allKeys = Object.keys(options);
    var optionKey = allKeys[optionIndex];

    var vals = options[optionKey];

    for (var i = 0; i < vals.length; i++) {
        current[optionKey] = vals[i];

        if (optionIndex + 1 < allKeys.length) {
            getCombinations(options, optionIndex + 1, results, current);
        } else {
            // The easiest way to clone an object.
            var res = JSON.parse(JSON.stringify(current));
            results.push(res);
        }
    }

    return results;
}

像這樣使用它:

var results = getCombinations(options, 0, [], {});

這是一個有效的JSFiddle 示例

這是最近復活的,我認為現代 JS 提供了一種更簡潔的方式來編寫它。

 const crossproduct = (xss) => xss.reduce((xs, ys) => xs.flatMap(x => ys.map(y => [...x, y])), [[]]) const combinations = (o, keys = Object .keys (o), vals = Object .values (o)) => crossproduct(vals).map(xs => Object.fromEntries(xs.map ((x, i) => [keys[i], x]))) const options = {optionOne: [true, false], optionTwo: [true, false], optionThree: [null, {property1: 9, property2: 7}, {property1: 4, property2: 12}, {property1: 16, property2: 14}]} console .log (JSON .stringify ( combinations (options) , null, 4))
 .as-console-wrapper {max-height: 100% !important; top: 0}

我們從一個crossproduct函數開始,例如,它需要

[[1, 2], ['a', 'b', 'c'], ['T', 'F']]

並返回

[
  [1, 'a', 'T'], [1, 'a', 'F'], [1, 'b', 'T'], [1, 'b', 'F'], [1, 'c', 'T'], [1, 'c', 'F'], 
  [2, 'a', 'T'], [2, 'a', 'F'], [2, 'b', 'T'], [2, 'b', 'F'], [2, 'c', 'T'], [2, 'c', 'F']
]

然后combinations使用Object.keysObject.values將我們的對象分開,將值傳遞給crossproduct ,然后對於結果中的每個數組,映射值,將相應的鍵與每個值相關聯,然后使用Object.fromEntries重新混合對象.

這個順序對我來說似乎是結果的邏輯順序。 但是,如果我們將返回的crossproduct表達式替換為以下內容,我們將得到問題中提到的順序:

  xss .reduce ((xs, ys) => ys .flatMap (y => xs .map (x => [...x, y])), [[]])

這是基於 Dmytro 的回答的改進:

function getPermutations(object, index = 0, current = {}, results = []) {
  const keys = Object.keys(object);
  const key = keys[index];
  const values = object[key];

  for (const value of values) {
    current[key] = value;
    const nextIndex = index + 1;

    if (nextIndex < keys.length) {
      this.getPermutations(object, nextIndex, current, results);
    } else {
      const result = Object.assign({}, current);
      results.push(result);
    }
  }
  return results;
}

改進:

  • 適用於任何類型的值,即使該值是一個函數
  • 默認參數值,可以很容易地調用: const p = getPermutations(object);
  • 細微的語義改進

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM