6

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?

2
  • What about the Criteria object? What should happen? Should it be discarded? Commented Apr 30, 2019 at 4:40
  • Yes Criteria object can be discarded and want to get the single object as above Commented Apr 30, 2019 at 4:44

5 Answers 5

6

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

Sign up to request clarification or add additional context in comments.

Comments

4

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)

3 Comments

Thanks, is there any possibility with the object key order?
@UI_Dev hopefully this link stackoverflow.com/questions/5525795/… will help you
@UI_Dev someone did
2

Assuming you want to exclude all the properties whose value is an object maybe you can go with this generic idea that uses Object.entries() to traverse the inner objects and some destructuring features.

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((obj, {id, ...rest}) =>
{
    Object.entries(rest).forEach(([k, v]) =>
    {
        if (Object(v) !== v) obj[`${k}-${id}`] = v;
    });

    return obj;
}, {});

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

Comments

1

Oh, man... I just got beat. Here's my solution.

let arr= [] // hold the final object array
let keys = [] // temp item to hold the value of each key

    // iterate over each key
    Object.keys(input).forEach((key) => {  
    let pair = key.split('-') // split the key into the real key and the index

    // if the index isn't in the array, push it there (this keeps the same order)
    if (keys.indexOf(pair[1])===-1) { 
        keys.push(pair[1])
    }

    // use object.assign to add the keys to the existing object in the right place in the array. 
    arr[keys.indexOf(pair[1])] = Object.assign({}, arr[keys.indexOf(pair[1])], {[pair[0]]: input[key]}, { id: pair[1] }) 

})

Comments

0

function getFilteredData(arr) {
  const result = {};
  arr.forEach(item => {
    const { id, Criteria, ...rest } = item;
    Object.entries(rest).map(([key, value]) => {
      result[`${key}-${id}`] = value;
    });
  });
  return result;
}

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

console.log(getFilteredData(arr));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.