-2

I need to convert an array of objects to an object of objects in JavaScript. The ID of the book should be the ID of each object from the array.

Array that I have:

[{
   "author" : "cccc",
   "catid" : 22,
   "id" : 25,
   "logo" : "logo",
   "name" : "Book c",
   "size" : 84777
 }, {
   "author" : "ddd",
   "catid" : 22,
   "id" : 26,
   "logo" : "logo",
   "name" : "Book d",
   "size" : 105139
 }]

Object that I need:

 {
 "25":{
   "author" : "bbbb",
   "catid" : 22,
   "logo" : "logo",
   "name" : "Book b",
   "size" : 73386
 }, 
 "26":{
   "author" : "cccc",
   "catid" : 22,
   "logo" : "logo",
   "name" : "Book c",
   "size" : 84777
 }}
crashmstr
  • 28,043
  • 9
  • 61
  • 79
Kh.Nomani
  • 185
  • 2
  • 12
  • 2
    [There is no such thing as a JSON Object](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/), nor a JSON array. – Heretic Monkey May 28 '19 at 13:31
  • What have you tried to do? There are many questions on this site about [grouping arrays into an object](https://stackoverflow.com/q/40774697/215552) – Heretic Monkey May 28 '19 at 13:33
  • 1
    Possible duplicate of [Group array of object nesting some of the keys with specific names](https://stackoverflow.com/questions/48425797/group-array-of-object-nesting-some-of-the-keys-with-specific-names) – Heretic Monkey May 28 '19 at 13:37

2 Answers2

3

You could use reduce:

const arr = [{
  "author": "aaaa",
  "catid": 22,
  "id": 23,
  "name": "Book a",
  "size": 56658
}, {
  "author": "bbbb",
  "catid": 22,
  "id": 24,
  "logo": "logo",
  "name": "Book b",
  "size": 73386
}, {
  "author": "cccc",
  "catid": 22,
  "id": 25,
  "logo": "logo",
  "name": "Book c",
  "size": 84777
}, {
  "author": "ddd",
  "catid": 22,
  "id": 26,
  "logo": "logo",
  "name": "Book d",
  "size": 105139
}]

const obj = arr.reduce((a, {id, ...obj}) => (a[id] = obj, a), {})

console.log(obj)

Reduce will loop over each object in the array, and the code inside will append the object to the accumulator, by id and then return that as an object.

Kobe
  • 6,226
  • 1
  • 14
  • 35
  • 1
    You could simplify it to: `acc[id] = obj` – adiga May 28 '19 at 13:35
  • Thanks, forgot you could do that @adiga – Kobe May 28 '19 at 13:36
  • @Kobe this works fine on a small chunk of data but after running this for a JSON of 4000 nodes, Firefox shows nothing, not even an error message. How can I run this script against a large chunk of data? – Kh.Nomani May 28 '19 at 15:30
  • I would recommend breaking the 4000 nodes down into smaller chunks. If you are rendering that many, it is a very bad idea since it will eat up your memory very quickly. This is what pagination is for. – Kobe May 28 '19 at 17:34
-1

The problem with the approach given above is it is limited to objects where the new object key is going to be id. Lets abstract this so the function is re-usable in all situations!

As stated above in your query, you want to convert a JSON Array called BookArray into a JSON Object called BookObject as follows.

const bookArray = [{
   "author" : "cccc",
   "catid" : 22,
   "id" : 25,
   "logo" : "logo",
   "name" : "Book c",
   "size" : 84777
 }, {
   "author" : "ddd",
   "catid" : 22,
   "id" : 26,
   "logo" : "logo",
   "name" : "Book d",
   "size" : 105139
 }]

Your resulting bookObject after processing should look like this.
const bookObject = {
 "25":{
   "author" : "bbbb",
   "catid" : 22,
   "logo" : "logo",
   "name" : "Book b",
   "size" : 73386
 }, 
 "26":{
   "author" : "cccc",
   "catid" : 22,
   "logo" : "logo",
   "name" : "Book c",
   "size" : 84777
 }}

const arrayToObject = (array, keyField) =>
   array.reduce((obj, item) => {
     obj[item[keyField]] = item
     return obj
   }, {})

const bookObject = arrayToObject(bookArray, "id")
console.log(bookObject[idToSelect])

The above code now accepts a keyField which allows us to use this function to convert any array of objects. Not just those who have the field id. This is important for reusability of our code.

Srikanth J
  • 388
  • 2
  • 12
  • You output will include the keyfield in the object too, which is not what OP has asked for. – Kobe May 28 '19 at 14:13
  • Hi @Kobe, providing an elegant solution that allows for a lot more flexibility in order to select an element from an Object could help scale the solution and apply it in multiple ways. – Srikanth J May 28 '19 at 15:24
  • I didn't say that, I said that OP didn't ask for ID to be in the output, which you have done. You would have to manually remove the key and value to get the desired output. – Kobe May 28 '19 at 15:26