0

I have an array of strings:

["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"]

Where each string has a meaning. For example if we consider the first string i.e., "aa-q1-true" Here the first part - aa is the quiz answer, middle part - q1 is the question and true, the last part is the answer status. Status can be true or false. This rule applies for each of the string inside the array.

Now I want to convert it into an array of objects like the following -

[
    0: [{
        quizAns: [{aa: true}, {bb: false}, {cc: true}]
        quizQuestion: q1
    }]

    1: [{
        quizAns: [{aa: true}, {xx: false}, {yy: true}]
        quizQuestion: q2
    }]

    2: [{
        quizAns: [{mm: true}, {mn: false}, {qr: false}]
        quizQuestion: q3
    }]
]

I just could not able to apprehend the logic to do this on my own. If you can just gimme some ideas or solution, it would be very helpful. Thank you so much for your time.

4 Answers 4

3

You would want to split each item by -, and then you get the first and last item to get your answer object, and the middle to get which question it belongs to, then you just iteratively construct the solution:

let ans = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"].map((s) => s.split('-')).reduce((carry, current) => {
    let existingIndex = carry.findIndex((item) => item.quizQuestion === current[1]);
    if (existingIndex === -1) {
        carry.push({quizAns: [], quizQuestion: current[1]});
        existingIndex = carry.length - 1;
    }
    carry[existingIndex].quizAns.push({[current[0]]: current[2]});
    return carry;
}, []);

console.log(ans);

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

Comments

2

Just another approach with less code

const resultMap = array.reduce((acc, item) => {
  // current data
  const [answer, quizQuestion, status] = item.split("-");
  // previous answers
  const previousAnswers = acc[quizQuestion] ? acc[quizQuestion].quizAns : [];
  // new answers
  const newAnswers = [...previousAnswers, { [answer]: status }];
  return { ...acc, [quizQuestion]: { quizQuestion, quizAns: newAnswers } };
}, {});

const result = Object.values(resultMap) 
console.log(result)

Comments

1

Just an another approach. Has less looping over the array than the other answer.

let questions = {  };
let ans = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"]
            .reduce((acc, curr) => {
                let elements = curr.split("-");
                let obj = {};
                obj[elements[0]] = elements[2];

                if (questions[elements[1]]) {
                    questions[elements[1]].push(obj);
                } else {
                    questions[elements[1]]= [obj];
                }
            }, {})
let result = [];
for (let prop in questions) {
    result.push({ "quizAns": questions[prop], "quizQuestion": prop });
}
console.log(result);

Comments

1

I am not a big fan of array.reduce syntax cause of readability factor.

This loop will work, even if the input comes in a scrambled fashion.

const a = ["aa-q1-true", "bb-q1-false", "cc-q1-true", "aa-q2-true", "xx-q2-false", "yy-q2-true", "mm-q3-true", "mn-q3-false", "qr-q3-false"];let results = [];

const retObj = (que, ans) => {
  const obj = {};
  obj[`${que}`] = ans;
  return obj;
};

for (let i in a){
  let currEleArr = a[i].split("-");
  let tarInd = parseInt(currEleArr[1].split("")[1]) - 1;
  let que = currEleArr[0];
  let ans= currEleArr[2];

  if (!results[tarInd])
    results[tarInd] = [{quizAns: []}];
  
  if(!results[tarInd][0].quizQuestion) 
  results[tarInd][0]["quizQuestion"] = `q${tarInd + 1}`;
  
  results[tarInd][0].quizAns.push(retObj(que, ans));
   
}

console.log(results);

Comments

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.