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 bining .map()
and .filter()
, but it didn't work.
For example:
const obj = data.map(e => e.q).filter(s => s.a)
Thanks.
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 bining .map()
and .filter()
, but it didn't work.
For example:
const obj = data.map(e => e.q).filter(s => s.a)
Thanks.
Share Improve this question edited Oct 29, 2019 at 18:14 Emile Bergeron 17.4k5 gold badges85 silver badges131 bronze badges asked Oct 29, 2019 at 17:50 storagemode11storagemode11 8958 silver badges12 bronze badges6 Answers
Reset to default 8You 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)
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);
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);
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)
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
}, {})
Here you go:
const obj = data.filter(s => s.a).map(e => ({[e.q]: e.a}))