Все возможные комбинации ключей и значений объекта с рекурсией в JS - PullRequest
0 голосов
/ 31 октября 2019

Вот что я написал: (ключ в заголовке - это опора)

var data = {
    dup_by: ['prop1', 'prop2', 'prop3'],
    prop1: ['val11', 'val12'],
    prop2: ['val21', 'val22'],
    prop3: ['val31', 'val32', 'val33'],
    test_obj: {},
    test_obj_arr: []
};

var dupRecursion = function(prop_index) {
      let prop_name = data.dup_by[prop_index]
      data[prop_name].forEach((value) => {
        data.test_obj[prop_name] = value
        console.log(prop_name)
        console.log(value)
        console.log(data.test_obj)
        if (prop_index == 0) {
          data.test_obj_arr = [data.test_obj, ...data.test_obj_arr]
          console.log(data.test_obj_arr)
        } else {
          dupRecursion(prop_index - 1)
        }
      })
      return;
    };

dupRecursion(data.dup_by.length - 1)

Вот ожидаемый результат:

data.test_obj_arr = [{prop1: 'val11', prop2: 'val21', prop3: 'val31'},
{prop1: 'val11', prop2: 'val21', prop3: 'val32'},
{prop1: 'val11', prop2: 'val21', prop3: 'val33'},
{prop1: 'val11', prop2: 'val22', prop3: 'val31'},
{prop1: 'val11', prop2: 'val22', prop3: 'val32'},
{prop1: 'val11', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val21', prop3: 'val31'},
{prop1: 'val12', prop2: 'val21', prop3: 'val32'},
{prop1: 'val12', prop2: 'val21', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val31'},
{prop1: 'val12', prop2: 'val22', prop3: 'val32'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'}]

Есть несколько решений для комбинаций массивоввместо объектов vals и props.

Я пробовал некоторые изменения в порядке, но все они приводят к одному и тому же выводу:

data.test_obj_arr = [{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'},
{prop1: 'val12', prop2: 'val22', prop3: 'val33'}]

Поскольку журналы выходят, как и ожидалось:

console.log(prop_name)
console.log(value)

Но это не так:

console.log(data.test_obj)
console.log(data.test_obj_arr)

Я считаю, что проблема в задании:

data.test_obj[prop_name] = value

Единственно, это работает, но не внутри рекурсии. ,Пытался использовать Object.Assign, и он тоже не работал.

Все эти функции, насколько мне известно, являются синхронизированными функциями.

Чего мне не хватает?

1 Ответ

0 голосов
/ 31 октября 2019

Создайте двумерный массив каждого prop_x значения. Затем создайте декартово произведение массива. Переберите комбинации и создайте объект для каждой комбинации с dup_by в качестве ключей

const input = {
    dup_by: ["prop1", "prop2", "prop3"],
    prop1: ["val11", "val12"],
    prop2: ["val21", "val22"],
    prop3: ["val31", "val32", "val33"],
    test_obj: {},
    test_obj_arr: [],
}

const keys = input.dup_by,
      matrix = keys.map(k => input[k])

// https://stackoverflow.com/a/57597533/3082296
const combos = matrix.reduce((acc, curr, i) =>
  acc.flatMap(c => curr.map(n => [].concat(c, n)))
)

const createObject = (values) =>
  Object.fromEntries(
    keys.map((k, i) => [k, values[i]])
  )

const output = combos.map(createObject)

console.log("matrix: ", JSON.stringify(matrix))
console.log("combos: ", JSON.stringify(combos))
console.log(output)

Если Object.fromEntries() не поддерживается, вы можете использовать reduce для создания объекта из массива ключей и значений

const createObject = (values) =>
  keys.reduce((acc, k, i) => (acc[k] = values[i], acc), {})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...