使用map变换数组并缩小

时间:2019-04-04 17:44:06

标签: javascript

我从Web服务获得了类似的数组:

const a = [ { label: 'A', value: 100 }, { label: 'B', value: 200 } ];
const b = [ { label: 'A', value: 50 }, { label: 'B', value: 300 } ];
const c = [ { label: 'A', value: 20 }, { label: 'B', value: 130 } ];
const d = [ { label: 'A', value: 10 }, { label: 'B', value: 25 } ];

,我想拥有类似的东西(处于React状态):

[ 
    { label: 'A', a: 100, b: 50, c: 20, d: 10 }, 
    { label: 'B', a: 200, b: 300, c: 130, d: 25 } 
]

使用现代JavaScript,我猜想是mapreduce

编辑:

我一开始并不清楚。我想在获取新数据时更新状态。

如果我当前的状态是:

[ 
    { label: 'A', a: 100, b: 50, c: 20, d: 10 }, 
    { label: 'B', a: 200, b: 300, c: 130, d: 25 } 
]

我得到

{ title: "a", values: [ { label: 'A', value: 12 }, { label: 'B', value: 13 } ] };

我想将状态更新为

[ 
    { label: 'A', a: 12, b: 50, c: 20, d: 10 }, 
    { label: 'B', a: 13, b: 300, c: 130, d: 25 } 
]

我最好的尝试是:

myFunction().then(data => {
  const {chartData} = this.state;
  chartData[data.title] = Object.keys(data.values).map(key => ({
    label: chartData[data.title] || data.values[key].label,
    [data.title]: data.values[key].value,
    ...chartData[data.title]
  });
  this.setState({chartData});
})

4 个答案:

答案 0 :(得分:1)

const glue = (label, ...vars) => ([].concat(vars).filter(i => i.label === label).reduce((agg, i) => ({ ...agg, ...i }), {}));

其中

glue('A', [a,b,c,d]);
glue('B', [a,b,c,d]);
// .. and so on
`

答案 1 :(得分:1)

这里的想法是

  • 将所有值组合在一个数组中
  • 使用数组保留字母
  • 遍历组合数组,并为组合数组中的每个元素根据组合数组的索引向标签和字母添加值

const a = [{ label: 'A', value: 100 }, { label: 'B', value: 200 }];
const b = [{ label: 'A', value: 50 }, { label: 'B', value: 300 }];
const c = [{ label: 'A', value: 20 }, { label: 'B', value: 130 }];
const d = [{ label: 'A', value: 10 }, { label: 'B', value: 25 }];

let alpha = [...'abcdefghijklmnopqrstuvwxyz']
let combine = [a,b,c,d]

let op = combine.reduce((op,inp,i) => {
  inp.forEach(({label,value}) => {
    op[label] = op[label] || {label}
    op[label][alpha[i]] = value
  })  
  return op
},{})

console.log(Object.values(op))

答案 2 :(得分:1)

使用Shorthand property names创建具有所有数组的对象(键名称是在输出中创建属性所必需的。您可以向该对象添加更多数组)。然后reduce Object.entries()

返回的条目

const a = [ { label: 'A', value: 100 }, { label: 'B', value: 200 } ];
const b = [ { label: 'A', value: 50 }, { label: 'B', value: 300 } ];
const c = [ { label: 'A', value: 20 }, { label: 'B', value: 130 } ];
const d = [ { label: 'A', value: 10 }, { label: 'B', value: 25 } ];

const input = { a, b, c, d };

const merged = Object.entries(input).reduce((r, [key, arr]) => {
  arr.forEach(({label, value}) => {
    r[label] = r[label] || { label };
    r[label][key] = value;
  })
  return r;
}, {})

console.log(Object.values(merged))

答案 3 :(得分:1)

您可以迭代给定的label数组,查找带有所需function update(state, { title, values }) { return values.reduce((r, { label, value }) => { var temp = r.find(o => o.label === label); if (!temp) r.push(temp = { label }); Object.assign(temp, { [title]: value }); return r; }, state); } var state = [{ label: 'A', a: 100, b: 50, c: 20, d: 10 }, { label: 'B', a: 200, b: 300, c: 130, d: 25 }], data = { title: "a", values: [{ label: 'A', value: 12 }, { label: 'B', value: 13 }] }; update(state, data); console.log(state);的项目并更新属性。

.as-console-wrapper { max-height: 100% !important; top: 0; }
String.trim()