Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map object if property is found in another array of objects

This is my case.

data: [
    {
      q: "question 1",
      a: "answer 1"
    }, 
    {
      q: "question 2"
    }
]

How can I map this into key: value pair so that the final output is { "question 1": "answer 1"}?

The trick is that only if a property exists then it should be assigned to the new object as above example { "question N": "answer N"}.

I have tried combining .map() and .filter(), but it didn't work.

For example:

const obj = data.map(e => e.q).filter(s => s.a)

Thanks.

like image 390
storagemode11 Avatar asked Oct 29 '19 17:10

storagemode11


People also ask

How to map multiple properties from array of objects in JavaScript?

1. Map multiple properties from array of objects JavaScript The array.map () method is iterated over the element of the array and modifies elements of the array by applying some operation and returning the modified element as a new array.

How do I map an object to an array?

// Takes the object to map and a function from (key, value) to mapped value. const mapObjectToArray = (obj, fn) => ( Object.keys (obj).map (k => fn (k, obj [k])) ); This may not work for all objects or all mapping functions, but it works for plain shallow objects and straightforward mapping functions which is all I needed.

How do I access the properties of an array of objects?

Every object from an array of objects is accessed as a function parameter in the callback function of Array.map (), the object properties can be de-structured or access directly as the item.property_name.

Why does map return an array instead of an object?

The reason that this works is due to the .map functions returning an array REQUIRING that you provide an explicit or implicit RETURN of an array instead of simply modifying an existing object.


4 Answers

You need to filter element first and then map

let data = [{q: "question 1",a: "answer 1"},{q: "question 2"}]

const obj = data.filter(s => s.a)
                .map(({q,a}) => ({ [q]: a }))

console.log(obj)

Can we get output as object, you can use reduce and build an Object,

let data = [{q: "question 1",a: "answer 1"},{q: "question 2"}]

const obj = data.reduce((op,{q,a})=>{
  if( a ) op[q] = a
  return op
},{})

console.log(obj)

In modern browser you can Object.fromEntries too

let data = [{q: "question 1",a: "answer 1"},{q: "question 2"}]

const obj = Object.fromEntries(data.filter(s => s.a)
                .map(({q,a}) => [q,a]))

console.log(obj)
like image 133
Code Maniac Avatar answered Oct 17 '22 02:10

Code Maniac


You can use map() and then filter().

let data = [{ q: "question 1", a: "answer 1" }, { q: "question 2" } ];

let result = data.map(item => {
  if (item.q && item.a) {
    return {
      [item.q]: item.a
    };
  }
}).filter(item => item); // Filter undefined values.

console.log(result);
like image 44
Nikhil Avatar answered Oct 17 '22 02:10

Nikhil


For a single object, you could take Object.fromEntries for creating a sigle object out of key/value pairs.

var data = [{ q: "question 1", a: "answer 1" }, { q: "question 2" }],
    result = Object.fromEntries(data
        .map(({ q, a }) => [q, a])
        .filter(([_, a]) => a)
    );

console.log(result);
like image 2
Nina Scholz Avatar answered Oct 17 '22 01:10

Nina Scholz


Using the reduce method effectively ensure u run a single loop with a conditional inside, instead of a map and a filter like the previous answers which are both definitely correct as well

let data = [{q: "question 1",a: "answer 1"},{q: "question 2"}]

const obj = data.reduce((acc,cur) => {
If(cur.a && cur.q) {
acc.push({[`${cur.q}`]: cur.a})
}. 
return acc
} ,[])

console.log(obj)
like image 1
MiDas Avatar answered Oct 17 '22 01:10

MiDas