Search code examples
javascriptecmascript-6ecmascript-2016

Convert array of strings into array of objects where each string itself has a separator


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.


Solution

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