数组对象到对象数组

我想更改作为嵌套数组对象的输入:


 const bullets = {

  one: [

  [

    1053, 2

  ],

  [

    2222, 7

  ]

],

  two: [

   [

    1053, 4

   ],

   [

    2222, 1

   ]

],

  three: [

   [

    1053, 6

   ],

   [

    2222, 12

   ],

],

};

到映射的输出中,它应该是这样的:


const result = [

  {label: 1053, a: 2, b: 4, c: 6},

  {label: 2222, a: 7, b: 1, c: 12}

]

所以基本上将输入对象数组中的值映射到结果中的键。对象的数量对应于唯一标签的数量(每个子数组中的“第一个”值)。每个子数组中的“second”值将“a”、“b”和“c”值分配给具有相应标签的对象。


我试过这样的事情:


const bullets = {

  one: [

    [

      1053, 2

    ],

    [

      2222, 7

    ]

  ],

  two: [

    [

      1053, 4

    ],

    [

      2222, 1

    ]

  ],

  three: [

    [

      1053, 6

    ],

    [

      2222, 12

    ],

  ],

};

let result = [];


Object.keys(bullets).reduce((p, c) => {

  result.push(bullets[p]

    .map(v => ({

      label: v[0],

      a: v[1],

      b: bullets[c].find(value => value[0] === v[0])[1],

      c: bullets[c].find(value => value[0] === v[0])[1],

    })));

  return c;

});


console.log([].concat(...result));

它适用于输入对象只有两个条目的情况,我只需要输出中的“a”和“b”值,但这显然是错误的,因为它导致 4 个对象而不是两个(“先前”值在reduce 曾经是第一个条目,在另一次迭代中是第二个条目 - 类似于 reduce 中的“当前”值)。

你知道这是否可以通过更简单的方式实现吗?也许某种 lodash 解决方案?我得到的一切都是意大利面条,没有确切的结果。提前感谢您的提示。


一只名叫tom的猫
浏览 181回答 4
4回答

忽然笑

如果已经存在具有当前标签的对象,您可以减少对象值并检查每次迭代。如果存在,则将值添加到它的数组中。现在,与其拥有 , 之类的属性a,b不如c我建议只使用数组并将它们解构为变量。这样您就不会受限于字母表或必须事先定义每个属性。const bullets = {  one:   [ [ 1053, 2 ], [ 2222,  7 ] ],  two:   [ [ 1053, 4 ], [ 2222,  1 ] ],  three: [ [ 1053, 6 ], [ 2222, 12 ] ]};const result = Object.values(bullets).reduce((acc, items) => {  for(const [key, value] of items) {    const index = acc.findIndex(({label}) => label === key);        index >= 0      ? acc[index].values.push(value)      : acc.push({label: key, values: [value]})  }    return acc;}, []);// All objectsconsole.log(result);// a, b, cfor(const item of result) {  const [a, b, c] = item.values;  console.log(a, b, c);}.as-console-wrapper { max-height: 100% !important; }

慕桂英546537

我将创建一个要使用的属性数组(例如a、b和c),然后创建一个由标签索引的对象,其值是数组的项目result。然后您可以遍历输入并根据需要插入值: const bullets = {  one: [  [    1053, 2  ],  [    2222, 7  ]],  two: [   [    1053, 4   ],   [    2222, 1   ]],  three: [   [    1053, 6   ],   [    2222, 12   ],],};const properties = ['a', 'b', 'c'];const result = {};Object.values(bullets).forEach((arr, propIndex) => {  arr.forEach(([label, val]) => {    if (!result[label]) result[label] = { label };    result[label][properties[propIndex]] = val;  });});console.log(Object.values(result));  {label: 1053, a: 2, b: 4, c: 6},  {label: 2222, a: 7, b: 1, c: 12}]

婷婷同学_

我的回答更像是 C 风格,但它做同样的工作。const bullets = {  one: [  [    1053, 2  ],  [    2222, 7  ]],  two: [   [    1053, 4   ],   [    2222, 1   ]],  three: [   [    1053, 6   ],   [    2222, 12   ],],};var midResult = {}var results = []for (const key in bullets) {const arr = bullets[key];arr.forEach(elem => {    if (midResult.hasOwnProperty(elem[0])) {        midResult[elem[0]].push(elem[1])    }else{        midResult[elem[0]]  =[elem[1]]    }});}for (const key in midResult) {if (midResult.hasOwnProperty(key)) {    const arr = midResult[key];    var elem = {}    elem.label = key    arr.forEach( (e,i) =>{        elem[String.fromCharCode(97+i)] = e    })    results.push(elem)}}console.log(results)

达令说

您暗示键名 ( 'a', 'b', 'c') 并不重要。这是一种重用原始名称 ( 'one', 'two', 'three') 的技术。const transform = (bullets) => Object .entries (Object .entries (bullets)  .reduce ((a, [name, xs]) =>     xs .reduce (      (a, [label, value]) => ({...a, [label]: [...(a [label] || []), [name, value]]}),      a    ), {}  )) .map (([label, values]) => ({label: Number(label), ...Object .fromEntries (values)}))const bullets = {one: [[1053, 2], [2222, 7]], two: [[1053, 4], [2222, 1]], three: [[1053, 6], [2222, 12]]}console .log (  transform (bullets)).as-console-wrapper {max-height: 100% !important; top: 0}我们分几步进行。调用Object .entries (bullets)产生这个:[  ["one", [[1053, 2], [2222, 7]]],   ["two", [[1053, 4], [2222, 1]]],   ["three", [[1053, 6], [2222, 12]]]]然后双重归约把它变成这样:{  "1053": [["one", 2], ["two", 4], ["three", 6]],   "2222": [["one", 7], ["two", 1], ["three", 12]]}然后我们Object .entries再次调用这个结果得到[  ["1053", [["one", 2], ["two", 4], ["three", 6]]],   ["2222", [["one", 7], ["two", 1], ["three", 12]]]]最后,通过map调用 using Object.fromEntries,我们把它变成[  {label: 1053, one: 2, two: 4, three: 6,   {label: 2222, one: 7, two: 1, three: 12}]如果您确实需要密钥转换,我们可以在调用中提供它们,如下所示:transform (bullets, {one: 'a', two: 'b', three: 'c'})只需对代码稍作修改。const transform = (bullets, keys) => Object .entries (Object .entries (bullets)  .reduce ((a, [name, xs]) =>     xs .reduce (      (a, [label, value]) => ({...a, [label]: [...(a [label] || []), [keys[name] || name, value]]}),      a    ), {}  )) .map (([label, values]) => ({label: Number(label), ...Object .fromEntries (values)}))const bullets = {one: [[1053, 2], [2222, 7]], two: [[1053, 4], [2222, 1]], three: [[1053, 6], [2222, 12]]}console .log (  transform (bullets, {one: 'a', two: 'b', three: 'c'})).as-console-wrapper {max-height: 100% !important; top: 0}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript