7

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.

6 Answers 6

8

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)

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

4 Comments

Thanks, is it possible that this is object, so: { "question 1": "answer 1" }
@storagemode11 have a look at the second snippet
@CodeManiac, Looks great, thanks. What if obj has some data, so we don't want to reassign to it, but instead just to append data?
@storagemode11 you can merge two object. How to merge two objects in JS, and if obj is an array then you can simply concat values
4

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

3 Comments

Code Maniac's answer does this, but better. Filtering first reduces the complexity of the mapping.
Thanks, is it possible that this is object, so: { "question 1": "answer 1" }
@storagemode11 - If you have multiple items in array, then you'll get multiple objects. If you want to access just the first object you can do it as result[0].
2

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

Comments

1

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)

1 Comment

Thanks Emile. Typed the answer from my phone.
1

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 
    }, {})

Comments

-1

Here you go:

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

7 Comments

Why does one get downvoted for that, this is a perfectly correct answer and even more compact than most of the other ones. Anyone care to explain?
Not the downvoter, but this is not having any difference with my answer, except some spacing removed. also code only answers are not considered as good practice on so
It's the same thing as the top answer, but on oneline... It brings nothing new here. Code without explanation is another reason for a downvote.
@onetyone I have not downvoted this either, but the problem is probably just with simply giving an answer without teaching anything. For the most part I don't think question askers are seeking merely solutions, but knowledge in general. Like, a great answer would not just give a solution, but would explain what the solution does, why the answerer has chosen such a methodology, and would perhaps directly quote and/or link to any applicable documentation, etc.
"I don't think question askers are seeking merely solutions" It's not just about the asker, it's about the quality of the content as a whole. Since an answer like this brings nothing to the thread, even if it works, it won't be well received by the community.
|

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.