Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert array of objects to single object which has dynamic key in typescript

This question might be similar to frequently asked one, but this one has some different approach.

In my angular 7 application, I have the following 5 arrays which needs to be converted to the below single object with dynamic key based on the id.

{
  "enabled-41": true,
  "enabled-42": true,
  "enabled-43": true,
  "enabled-44": true,
  "enabled-45": false,
  "abc-41": "some description 1",
  "abc-42": "some description 12",
  "abc-43": "some description 123",
  "abc-44": "some description 1234",
  "abc-45": null,
  "def-41": "some description 2",
  "def-42": "some description 23",
  "def-43": "some description 234",
  "def-44": "some description 2345",
  "def-45": null,
  "type-41": "def",
  "type-42": "abc",
  "type-43": "def",
  "type-44": "abc",
  "type-45": null,
  "weight-41": "25",
  "weight-42": "25",
  "weight-43": "25",
  "weight-44": "25",
  "weight-45": null
}

let arr = [
  {
    "id": 41,
    "abc": "some description 1",
    "def": "some description 2",
    "type": "def",
    "Criteria": {
      "id": 5,
      "question": "follow-up",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 42,
    "abc": "some description 12",
    "def": "some description 23",
    "type": "abc",
    "Criteria": {
      "id": 1,
      "question": "coverage",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 43,
    "abc": "some description 123",
    "def": "some description 234",
    "type": "def",
    "Criteria": {
      "id": 4,
      "question": "Price",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 44,
    "abc": "some description 1234",
    "def": "some description 2345",
    "type": "abc",
    "Criteria": {
      "id": 3,
      "question": "Exchange",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 45,
    "Criteria": {
      "id": 2,
      "definition": "definition conent",
      "question": "Random",
      "status": true
    },
    "type": null,
    "abc": null,
    "def": null,
    "weight": 0,
    "enabled": false
  }
];

let result = arr.reduce(function(obj, item) {
    obj[item] = item.value;
    return obj;
}, {})

console.log(result);

I have tried using reduce function, but cannot able to get the right way to convert to a single object with the above format based on dynamic key (joining id with hypen).

Can someone help me with this?

like image 643
UI_Dev Avatar asked Apr 30 '19 04:04

UI_Dev


People also ask

How do you convert an array of objects to a single object in TypeScript?

assign() method to convert an array of objects to a single object. This merges each object into a single resultant object. The Object. assign() method also merges the properties of one or more objects into a single object.

How do you grab the key of an object?

Use object. keys(objectName) method to get access to all the keys of object. Now, we can use indexing like Object. keys(objectName)[0] to get the key of first element of object.

How do you transform an array into an object?

To convert an array to an object, use the reduce() method to iterate over the array, passing it an object as the initial value. On each iteration, assign a new key-value pair to the accumulated object and return the result.


2 Answers

You can use reduce with Object.keys, and place all keys you wish to exclude in an array and check against that:

let arr = [{"id":41,"abc":"some description 1","def":"some description 2","type":"def","Criteria":{"id":5,"question":"follow-up","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":42,"abc":"some description 12","def":"some description 23","type":"abc","Criteria":{"id":1,"question":"coverage","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":43,"abc":"some description 123","def":"some description 234","type":"def","Criteria":{"id":4,"question":"Price","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":44,"abc":"some description 1234","def":"some description 2345","type":"abc","Criteria":{"id":3,"question":"Exchange","definition":"definition content","status":true},"weight":25,"enabled":true},{"id":45,"Criteria":{"id":2,"definition":"definition conent","question":"Random","status":true},"type":null,"abc":null,"def":null,"weight":0,"enabled":false}];

let exclude = ["id", "Criteria"];

let result = arr.reduce((acc, curr) => {
  let id = curr.id;
  Object.entries(curr).forEach(([k, v]) => {
    if (!exclude.includes(k)) acc[`${k}-${id}`] = v;
  });
  return acc;
}, {});

console.log(result);
like image 101
Jack Bashford Avatar answered Sep 28 '22 02:09

Jack Bashford


You code is almost there. But object keys order is not guaranteed. Inside the reduce callback function add the keys in the accumulator and corresponding value.

Use template literals & square notation while creating the object keys

let arr = [{
    "id": 41,
    "abc": "some description 1",
    "def": "some description 2",
    "type": "def",
    "Criteria": {
      "id": 5,
      "question": "follow-up",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 42,
    "abc": "some description 12",
    "def": "some description 23",
    "type": "abc",
    "Criteria": {
      "id": 1,
      "question": "coverage",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 43,
    "abc": "some description 123",
    "def": "some description 234",
    "type": "def",
    "Criteria": {
      "id": 4,
      "question": "Price",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 44,
    "abc": "some description 1234",
    "def": "some description 2345",
    "type": "abc",
    "Criteria": {
      "id": 3,
      "question": "Exchange",
      "definition": "definition content",
      "status": true
    },
    "weight": 25,
    "enabled": true
  },
  {
    "id": 45,
    "Criteria": {
      "id": 2,
      "definition": "definition conent",
      "question": "Random",
      "status": true
    },
    "type": null,
    "abc": null,
    "def": null,
    "weight": 0,
    "enabled": false
  }
];

let result = arr.reduce(function(obj, item) {
  obj[`enabled-${item.id}`] = item.enabled;
  obj[`abc-${item.id}`] = item.abc;
  obj[`def-${item.id}`] = item.def;
  obj[`type-${item.id}`] = item.type;
  obj[`weight-${item.id}`] = item.weight;
  return obj;
}, {});
console.log(result)
like image 31
brk Avatar answered Sep 28 '22 02:09

brk