Erick
Erick

Reputation: 1146

How to get the dynamic values in an object

I have an object like

var object = {
    id:101,
    question1: "First question",
    answer1: "First answer",
    question2: "Second question",
    answer2: "Second answer",
    age: "5 hours"
}

I wish to add all the question and answers to a different array. like

 var qa = [{
            question1: "First question",
            answer1: "First answer",
        },{
            question2: "Second question",
            answer2: "Second answer",
        }
    ], 

However, the issue I am facing is that there can be dynamic keys in the parent object for question and answers.

Upvotes: 0

Views: 78

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386660

You could take same keys for the array and look first for wanted properties and then add them to the result set.

var object = { id: 101, question1: "First question", answer1: "First answer", question2: "Second question", answer2: "Second answer", age: "5 hours" },
    keys = ['question', 'answer'],
    result = Object.entries(object).reduce((r, [key, value]) => {
        let k = keys.find(k => key.startsWith(k)); // find Q or A
        if (!k) return r;   // not a Q or A, return the accumulator
        let i = key.slice(k.length) - 1; // get the idx and subtract one
        r[i] = r[i] || {};  // create an object if none already
        r[i][k] = value;    // add the value of the question or answer
        return r;           // return the accumulator
    }, []);

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

Upvotes: 2

mplungjan
mplungjan

Reputation: 178255

Try this assuming same suffix for both Q and A

const object = {
  id: 101,
  question1: "First question",
  answer1: "First answer",
  question1a: "First sub question",
  answer1a: "First sub answer",
  question2: "Second question",
  answer2: "Second answer",
  age: "5 hours"
}
const qa = Object.keys(object)
  .filter(key => key.indexOf("question") === 0) // get all questions
  .map(key => {
      const aKey = "answer" + key.replace("question", ""); // get the idx
      return { [key]:object[key], [aKey]:object[aKey] }; // return an object
      })
console.log(qa);

If you have ascending idx, you can

const object = {
  id: 101,
  question1: "First question",
  answer1: "First answer",
  question2: "Second question",
  answer2: "Second answer",
  question3: "Third question",
  answer3: "Third answer",
  age: "5 hours"
};
const qa = []
Object.keys(object).filter(key => key.indexOf("question") === 0) // get all questions
  .forEach(key => {
    const idx = key.replace("question", "");
    const aKey = "answer" + idx;
    qa[idx - 1] = {
      "question": object[key],
      "answer": object[aKey]
    }; // return an object
  })
console.log(qa);

Upvotes: 1

Rajneesh
Rajneesh

Reputation: 5308

You can first take entries of object then filter out the other static parts, after that you can reduce it and take Object.values():

var obj = {id:101,question1: "First question",answer1: "First answer",question2: "Second question",answer2: "Second answer",age: "5 hours"};

var result = Object.values(Object.entries(obj).filter(([k,v])=>k.match(/(question|answer)/)).reduce((acc, [k,v])=>{
  key = k.match(/\d+/)[0];
  acc[key] = {...(acc[key] || {}), ...{[k]:v}}
  return acc;
},{}));

console.log(result);

Upvotes: 0

Related Questions