Reputation: 895
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.
Upvotes: 7
Views: 2387
Reputation: 562
Here you go:
const obj = data.filter(s => s.a).map(e => ({[e.q]: e.a}))
Upvotes: -1
Reputation: 776
Here's what I believe you're trying to do, and this will account for multiple questions as well.
First, you need to use filter
to get rid of anything that doesn't have the a
property defined.
Then, you can use a reducer
function.
This reducer accumulates a brand new object (starting with {}
which is passed as the 2nd argument to reduce
). It assigns each property (question name) to each value (answer) and returns the new accumulated variable, until it's done iterating.
const data = [{q: "question 1", a: "answer 1"}, {q: "question 2"}, {q: "question 3", a: "answer 3"}]
const obj = data.filter(item => item.hasOwnProperty('a'))
.reduce(function(acc, cur) {
acc[cur.q] = cur.a
return acc
}, {})
Upvotes: 1
Reputation: 374
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)
Upvotes: 1
Reputation: 386736
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);
Upvotes: 2
Reputation: 37755
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)
Upvotes: 8
Reputation: 6641
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);
Upvotes: 4