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

javascript - Normalise array of objects & key by id - Stack Overflow

programmeradmin0浏览0评论

I'm looking to normalise some data returned from an API. Already using underscore within the project.

var res = [{
    badge_no: 123,
    id: 1,
    name: 'bob'
  }, {
    badge_no: 456,
    id: 2,
    name: 'bill'
  }, {
    badge_no: 789,
    id: 3,
    name: 'ben'
  },
  // etc
];

I'm looking to create a data structure that looks like:

var normalisedRes = [{
  1: {
    badge_no: 123,
    id: 1,
    name: 'bob'
  }
}, {
  2: {
    badge_no: 456,
    id: 2,
    name: 'bill'
  }
}, {
  3: {
    badge_no: 789,
    id: 3,
    name: 'ben'
  }
}];

It is important that I keep the id within the obj. I believe I can acplish this with reduce but I'm struggling.

Thanks for your help!

EDIT: This question has now been answered.

From some of the advice on here, I have decided to normalise the data to return an obj which looks like:

{ '1': {data}, '2':{data}, '3':{data} }

To do this I used reduce, as I originally thought I should:

var normalised = res.reduce((acc, person) => { acc[person.id] = person; return acc; }, {});

Thanks again for all the answers!

I'm looking to normalise some data returned from an API. Already using underscore within the project.

var res = [{
    badge_no: 123,
    id: 1,
    name: 'bob'
  }, {
    badge_no: 456,
    id: 2,
    name: 'bill'
  }, {
    badge_no: 789,
    id: 3,
    name: 'ben'
  },
  // etc
];

I'm looking to create a data structure that looks like:

var normalisedRes = [{
  1: {
    badge_no: 123,
    id: 1,
    name: 'bob'
  }
}, {
  2: {
    badge_no: 456,
    id: 2,
    name: 'bill'
  }
}, {
  3: {
    badge_no: 789,
    id: 3,
    name: 'ben'
  }
}];

It is important that I keep the id within the obj. I believe I can acplish this with reduce but I'm struggling.

Thanks for your help!

EDIT: This question has now been answered.

From some of the advice on here, I have decided to normalise the data to return an obj which looks like:

{ '1': {data}, '2':{data}, '3':{data} }

To do this I used reduce, as I originally thought I should:

var normalised = res.reduce((acc, person) => { acc[person.id] = person; return acc; }, {});

Thanks again for all the answers!

Share edited Jan 30, 2017 at 17:25 ste asked Jan 30, 2017 at 16:26 steste 632 silver badges8 bronze badges 6
  • 1 Can you share your code that you have tried so far? – Rajesh Commented Jan 30, 2017 at 16:27
  • 4 So you want an array of objects, with each of those objects containing a single key (its id)? How is that a "better" or normalized version of what you started with? Why do you want that structure? – gen_Eric Commented Jan 30, 2017 at 16:28
  • 3 Final structure makes no sense. Why would you need an array to wrap one object? – charlietfl Commented Jan 30, 2017 at 16:33
  • 1 Do you want the keys to be IDs or indexes (+1)? – ibrahim mahrir Commented Jan 30, 2017 at 16:46
  • 2 Please, edit in your question your last ment about keys being IDs. Also, avoid editing an answer into your question and instead, accept one of the answers, ment on it with your final decision if necessary. If none of the answers fit your needs, you are encouraged to provide your own and accept it. – Emile Bergeron Commented Jan 30, 2017 at 17:56
 |  Show 1 more ment

5 Answers 5

Reset to default 3

You could use Array#map with an object and set the key with id and return the object.

var array = [{ badge_no: 123, id: 1, name: 'bob' }, { badge_no: 456, id: 2, name: 'bill' }, { badge_no: 789, id: 3, name: 'ben' }],
    result = array.map(function (a) {
        var o = {};
        o[a.id] = a;
        return o;
   });

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

With ES6, you could use a puted property.

var array = [{ badge_no: 123, id: 1, name: 'bob' }, { badge_no: 456, id: 2, name: 'bill' }, { badge_no: 789, id: 3, name: 'ben' }],
    result = array.map(a => ({ [a.id]: a }));

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

You cant use integers as key in an object. So your example isnt possible. See this relatied issue: Javascript: Using integer as key in associative array?

You can do this with Array#map()

var res = [{badge_no:123, id:1, name:'bob'},{badge_no:456, id:2, name:'bill'},{badge_no:789, id:3, name:'ben'}];

var result = res.map(e => ({[e.id]: e}))
console.log(result)

If you want you can also use reduce() but map() should get the job done.

var res = [{badge_no:123, id:1, name:'bob'},{badge_no:456, id:2, name:'bill'},{badge_no:789, id:3, name:'ben'}];

var result = res.reduce((r, e) => (r.push({[e.id]: e}), r), [])
console.log(result)

Aren't these solutions counter intuitive thou, the point of using an HashTable over an array is that if you have to use Array.find((item)=>{...}) it has to go through each record to find the one you want, reduce will go through each item in the array, and map will return back a new array, ie: you will get an array with the objectKey:{...object}, the best thing to do will be to return an Hash from your backend, This is actually what firebase does for example

_.indexBy does exactly what is required.

发布评论

评论列表(0)

  1. 暂无评论