为了账号安全,请及时绑定邮箱和手机立即绑定

Javascript在按属性分组的数组中收集对象值

Javascript在按属性分组的数组中收集对象值

拉丁的传说 2022-01-01 18:34:12
我从 API 响应中收到以下数组:[   {group: '1', , value: 'a'}  {group: '1', , value: 'b'}  {group: '2', , value: 'c'}  {group: '2', , value: 'd'}]  我想将其转换为以下内容(希望收到的组顺序,值可以以任何方式排序):[  {group: '1', values: ['b', 'a'] },  {group: '2', values: ['c', 'd'] },]哪个 Javascript 函数将最有效地转换它?我可以通过以下方式做到这一点:let result = [];data.reduce((groupNumber, input) => {  if (!groupNumber[input.group]) {     groupNumber[input.group] = {group: input.group, values: []};     result.push(groupNumber[input.group]);  }  groupNumber[input.group].values.push(input);  return groupNumber;}, {});难道reduce要在此处使用了正确的功能?有没有更有效的方法?其次,会reduce保留结果中的顺序吗?如果我实际上首先接收第 1 组条目的数据,然后是第 2 组条目,依此类推,我result是否可以依赖类似的排序?请注意,我只关心组的顺序,而不关心组内的值。
查看完整描述

2 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

我会保存我的回复,因为我们有一个很好的解释,为什么您的方法很棒,因为您有O(N)计算复杂性(感谢对@CertainPerformance的精彩评论)并且您只迭代一次数组。


测试reduce方法是否保留对象键的顺序:


看起来reduce方法没有保留键的顺序。在这里,我们看到键是按顺序排序的,然后如何遍历源数组myArray,但是在 Chrome 浏览器中,这种行为是不可重现的(键是排序的):


var myArray = [{letter: 'c'}, {letter:'e'}, {letter: 'e'}, {letter:'b'}, {letter: 'c'}, {letter:'a'}, {letter:'b'}, {letter:'a'}, {letter: 'd'}, {letter: 'd'}, {letter: 'd'}, {letter: 'd'}];

var myOrderedKeys = myArray.reduce((a, {letter}) => {

a[letter] = a[letter] || letter;

a[letter] = letter;


return a;

}, {})


console.log(myOrderedKeys);


我们有多个字母的一个例子:


let notSimpleLetters = [{letter: 'ce'}, {letter:'ec'}, {letter: 'ec'}, {letter:'bw'}, {letter: 'ce'}, {letter:'aw'}, {letter:'ba'}, {letter:'aa'},

                    {letter: 'df'}, {letter: 'cb'}, {letter: 'dc'}, {letter: 'da'}];

let notSimpleKeys = notSimpleLetters.reduce((a, {letter}) => {

a[letter] = a[letter] || letter;

a[letter] = letter;


return a;

}, {})


console.log(notSimpleKeys);


查看完整回答
反对 回复 2022-01-01
?
LEATH

TA贡献1936条经验 获得超6个赞

实际上,无论是通过 usingreduce()还是任何其他Array方法,顺序都将被保留,因为它们将从索引 0 执行到array.


但reduce()主要用于将array元素累积成单个元素,这不是做这种事情的最佳方法,但也可以使用。


请注意,您使用的实际代码reduce()没有返回正确的输出。


在我看来,我认为在这种情况下Array.map()方法更好,但它应该与Array.filter()删除重复的元素结合使用map():


var result = data.map(v => {

  v.values = data.filter(e => e.group == v.group).map(x => x.value);

  delete v.value;

  return v;

}).filter(x => !x.values.some(e => !e));

演示:

let data = [{

  group: '1',

  value: 'a'

}, {

  group: '1',

  value: 'b'

}, {

  group: '2',

  value: 'c'

}, {

  group: '2',

  value: 'd'

}];



var result = data.map(v => {

  v.values = data.filter(e => e.group == v.group).map(x => x.value);

  delete v.value;

  return v;

}).filter(x => !x.values.some(e => !e));


console.log(result);


查看完整回答
反对 回复 2022-01-01
  • 2 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号