Javascript манипулирование объектами - PullRequest
1 голос
/ 03 августа 2020

надеюсь, что кто-то может дать мне подсказки для решения моей проблемы.

У меня есть объект со следующей схемой:

{
  "prop1": value1,
  "prop2": value2,
  "nested1": [{A},{B}],
  "nested2": [{C},{D}],
  "nested3": [{E},{F}],
}

то, что я хочу получить от моего исходного объекта, - это следующее:

{
    items: [
        {
            "prop1": value1,
            "prop2": value2,
            "nested1": {A},
            "nested2": {C},
            "nested3": {E},
        },
        {
            "prop1": value1,
            "prop2": value2,
            "nested1": {B},
            "nested2": {D},
            "nested3": {F},
        },      
    ]
}

items.length совпадает с длиной массива в nested1, nested2 et c исходного объекта. properties (2 в этом примере). Я не могу найти способ solid рефакторинга исходного объекта с использованием javascript собственных функций. Любая помощь приветствуется.

Ответы [ 6 ]

2 голосов
/ 03 августа 2020

Я немного изменил ваш пример и использовал строки, чтобы иметь действительный объект. Это был бы один из способов сделать это:

const input = {
  prop1: "value1",
  prop2: "value2",
  nested1: ["A","B"],
  nested2: ["C","D"],
  nested3: ["E","F"],
};

const output = new Array(input.nested1.length).fill().map((_, i) => ({
    prop1: input.prop1,
    prop2: input.prop2,
    nested1: input.nested1[i],
    nested2: input.nested2[i],
    nested3: input.nested3[i]
}));

console.log(output);
0 голосов
/ 03 августа 2020

Вот полностью универсальное c решение, вам не нужно знать имена свойств, даже имя свойства, содержащего массив. Это работает для любого количества свойств, если структура аналогична примеру в вопросе.

const source = {
    "prop1": 'value1',
    "prop2": 'value2',
    "nested1": [{A: 1}, {B: 2}],
    "nested2": [{C: 2}, {D: 4}],
    "nested3": [{E: 5}, {F: 6}]
  },
  items = [];
let len = 0;

// Get the length of the nested arrays
for (const [key, value] of Object.entries(source)) {
  if (Array.isArray(value)) {
    len = value.length;
    break;
  }
}
// Create item array objects
for (let n = 0; n < len; n++) {
  items.push({});
  for (const [key, value] of Object.entries(source)) {
    items[n][key] = (Array.isArray(value)) ? value[n] : value;
  }
}

console.log(items);

Сначала код просто ищет первый массив, а затем сохраняет длину найденного массива. После определения длины новые объекты и их свойства помещаются в массив items. Является ли значение непосредственно значением свойства или взято из массива, определяется типом свойства.

0 голосов
/ 03 августа 2020

Вы используете Array.from с обратным вызовом сопоставления.

const obj = {
  "prop1": 'value1',
  "prop2": 'value2',
  "nested1": ['A','B'],
  "nested2": ['C','D'],
  "nested3": ['E','F'],
};
const res = {items: Array.from({length: obj.nested1.length}, (_,i)=>({
  prop1: obj.prop1, prop2: obj.prop2,
  nested1: obj.nested1[i],
  nested2: obj.nested2[i],
  nested3: obj.nested3[i]
}))};
console.log(res);

Вы также можете map поверх любого из вложенных массивов.

const obj = {
  "prop1": 'value1',
  "prop2": 'value2',
  "nested1": ['A','B'],
  "nested2": ['C','D'],
  "nested3": ['E','F'],
};
const res = {
  items: obj.nested1.map((nested1,i)=>({
    prop1: obj.prop1, prop2: obj.prop2,
    nested1, nested2: obj.nested2[i], nested3: obj.nested3[i]
  }))
}
console.log(res);
0 голосов
/ 03 августа 2020

Общее c решение для произвольных случаев

function buildItems(obj) {
  const commonPairs = Object.entries(obj).reduce(
    (accumulate, [key, val]) =>
      Array.isArray(val) ? accumulate : { ...accumulate, [key]: val },
    {}
  )
  const arrayPairs = Object.entries(obj).reduce(
    (accumulate, [key, val]) =>
      !Array.isArray(val) ? accumulate : { ...accumulate, [key]: val },
    {}
  )

  if (Object.keys(arrayPairs).length === 0) {
    return [{ ...commonPairs }]
  }

  const res = []
  for (let i = 0; i < arrayPairs[Object.keys(arrayPairs)[0]].length; i++) {
    res.push({
      ...commonPairs,
      ...Object.keys(arrayPairs).reduce(
        (acc, key) => ({ ...acc, [key]: arrayPairs[key][i] }),
        {}
      ),
    })
  }

  return res
}

console.log(
  "1)",
  buildItems({
    prop1: "value1",
    prop2: "value2",
    nested1: [{ A: 1 }, { B: 1 }, { G: 1 }],
    nested2: [{ C: 1 }, { D: 1 }, { H: 1 }],
    nested3: [{ E: 1 }, { F: 1 }, { I: 1 }],
    nested4: [{ J: 1 }, { K: 1 }, { L: 1 }],
    nested5: [{ M: 1 }, { N: 1 }, { O: 1 }],
  }),
  "\n"
)

console.log(
  "2)",
  buildItems({
    prop1: "value1",
    prop2: "value2",
  }),
  "\n"
)

console.log(
  "3)",
  buildItems({
    prop1: "value1",
    prop2: "value2",
    nested1: [{ A: 1 }, { B: 1 }, { G: 1 }],
  }),
  "\n"
)
0 голосов
/ 03 августа 2020

Если вы новичок, вы можете выполнить вышеуказанную задачу просто так.

const input = {
  prop1: "value1",
  prop2: "value2",
  nested1: ["A","B"],
  nested2: ["C","D"],
  nested3: ["E","F"],
};

let arr1 ={
  prop1:input.prop1,
  prop2:input.prop2,
  nested1:input.nested1[0],
  nestend2:input.nested2[0],
  nested3:input.nested3[0],
}
let arr2 ={
  prop1:input.prop1,
  prop2:input.prop2,
  nested1:input.nested1[1],
  nestend2:input.nested2[1],
  nested3:input.nested3[1],
}

console.log({items:[arr1,arr2]});

0 голосов
/ 03 августа 2020

Использование map и деструктуризация

const convert = ({ nested1, nested2, nested3, ...rest }) => ({
  items: nested1.map((nested1, i) => ({
    ...rest,
    nested1,
    nested2: nested2[i],
    nested3: nested3[i],
  }))
});

const obj = {
  prop1: 'value1',
  prop2: 'value2',
  nested1: [{ 'A': 'a' }, { 'B': 'b' }],
  nested2: [{ 'C': 1 }, { 'D': 2 }],
  nested3: [{ 'E': 5 }, { 'F': 6 }],
};

console.log(convert(obj));
...