基于公共键/值对重新排列对象数组

时间:2017-06-09 09:09:23

标签: javascript arrays json multidimensional-array javascript-objects

我有以下对象数组:

[
   {
     message: 'This is a test',
     from_user_id: 123,
     to_user_id: 567
   },
   {
     message: 'Another test.',
     from_user_id: 123,
     to_user_id: 567
   },
   {
     message: 'A third test.',
     from_user_id: '456',
     to_user_id: 567
   }
]

如何构建一个新的对象数组,其中最外层的对象键基于原始数组中的公共键?

这就是我之后的事:

[
  {
    123: [
      {
        message: 'This is a test',
        from_user_id: 123,
        to_user_id: 567
      },
      {
        message: 'Another test.',
        from_user_id: 123,
        to_user_id: 567
      }
    ]
  },
  {
    456: [
      {
        message: 'A third test.',
        from_user_id: '456',
        to_user_id: 567
      }
    ]
  }
]

请注意,在第一个数组中,123的用户ID如何显示在两个对象中。这将是新数组中第一个元素的对象键。

4 个答案:

答案 0 :(得分:4)

您可以使用对象并将from_user_id属性作为对象的键。然后将实际对象推送到组。要获得最终结果,请迭代groups的键并为任何组构建新对象。



var data = [{ message: 'This is a test', from_user_id: 123, to_user_id: 567 }, { message: 'Another test.', from_user_id: 123, to_user_id: 567 }, { message: 'A third test.', from_user_id: '456', to_user_id: 567 }],
    groups = Object.create(null),
    result;

data.forEach(function (a) {
    groups[a.from_user_id] = groups[a.from_user_id] || [];
    groups[a.from_user_id].push(a);    
});

result = Object.keys(groups).map(function (k) {
    var temp = {};
    temp[k] = groups[k];
    return temp;
});

console.log(result);

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




与单循环方法一起



var data = [{ message: 'This is a test', from_user_id: 123, to_user_id: 567 }, { message: 'Another test.', from_user_id: 123, to_user_id: 567 }, { message: 'A third test.', from_user_id: '456', to_user_id: 567 }],
    result = data.reduce(function (groups) {
        return function (r, a) {
            var temp = {};
            if (!groups[a.from_user_id]) {
                groups[a.from_user_id] = [];
                temp[a.from_user_id] = groups[a.from_user_id]; 
                r.push(temp);
            }
            groups[a.from_user_id].push(a);
            return r;
        };
    }(Object.create(null)), []);

console.log(result);

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




答案 1 :(得分:3)

你可以全功能获取所有键过滤掉它并将其作为json对象映射回来

var b = a.map(key => key['from_user_id'])
var c = {}
b.map(elt => c[elt] = a.filter(k => k.from_user_id == elt))
console.log(c)

答案 2 :(得分:1)



var users = [
             {
               message: 'This is a test',
               from_user_id: 123,
               to_user_id: 567
             },
             {
               message: 'Another test.',
               from_user_id: 123,
               to_user_id: 567
             },
             {
               message: 'A third test.',
               from_user_id: '456',
               to_user_id: 567
             }
          ];
console.log(_.groupBy(users,'from_user_id'))

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
&#13;
&#13;

使用Lodash会让您变得非常轻松。假设你有:

var users = [
             {
               message: 'This is a test',
               from_user_id: 123,
               to_user_id: 567
             },
             {
               message: 'Another test.',
               from_user_id: 123,
               to_user_id: 567
             },
             {
               message: 'A third test.',
               from_user_id: '456',
               to_user_id: 567
             }
          ];

只有一行Lodash你想要完全想要

users = _.groupBy(users,'from_user_id')

答案 3 :(得分:1)

您只需初始化一个results数组,遍历数据数组并检查from_user_id数组中是否存在迭代results,在其上推送迭代对象,否则创建使用新from_user_id键的新对象。

这应该是你的代码:

var results = [];
arr.forEach(function(obj){
    let id = obj["from_user_id"];
    if(!results.some(function(r){
       return r[id];
    })){
        let el = {}; 
        el[id] = [];
        el[id].push(obj);
        results.push(el);
    }else{
        results.forEach(function(res){
            if(res[id]){
              res[id].push(obj);
            }
        });
    }
});

<强>演示:

var arr = [{
  message: 'This is a test',
  from_user_id: 123,
  to_user_id: 567
}, {
  message: 'Another test.',
  from_user_id: 123,
  to_user_id: 567
}, {
  message: 'A third test.',
  from_user_id: 456,
  to_user_id: 567
}];


var results = [];
arr.forEach(function(obj){
    let id = obj["from_user_id"];
    if(!results.some(function(r){
       return r[id];
    })){
        let el = {}; 
        el[id] = [];
        el[id].push(obj);
        results.push(el);
    }else{
        results.forEach(function(res){
            if(res[id]){
              res[id].push(obj);
            }
        });
    }
});
console.log(results);