最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Rearrange an array of objects based on a common keyvalue pair - Stack Overflow

programmeradmin9浏览0评论

I have the following array of 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
   }
]

How do I construct a new array of objects where the outermost object key is based on a mon key found in the original array?

This is what I'm after:

[
  {
    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
      }
    ]
  }
]

Notice how in the first array, the user ID of 123 shows up in two objects. That would be the object key for the first element in the new array.

I have the following array of 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
   }
]

How do I construct a new array of objects where the outermost object key is based on a mon key found in the original array?

This is what I'm after:

[
  {
    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
      }
    ]
  }
]

Notice how in the first array, the user ID of 123 shows up in two objects. That would be the object key for the first element in the new array.

Share Improve this question asked Jun 9, 2017 at 9:09 FaridFarid 1,6654 gold badges23 silver badges36 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 5

You could use an object and take the from_user_id property as key for the object. Then push the actual object to the group. For getting the final result, iterate the keys of groups and build a new object for any group.

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; }

Together with a single loop approach

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; }

You could go full functional get all the key filter it out and map it back as a json object

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)

You just need to initialize a results array, loop over your data array and check if the iterated from_user_id exists in the results array, push the iterated object on it, otherwise create a new object with the new from_user_id key.

This is how should be your code:

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);
            }
        });
    }
});

Demo:

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);

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./ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Using Lodash will make it super easy for you. Assuming you have :

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
             }
          ];

just in one line with Lodash and you'll get want you want exactly:

users = _.groupBy(users,'from_user_id')
发布评论

评论列表(0)

  1. 暂无评论