0

Im trying to build a new array of objects based on specs array of objects. There are some similar question already but didn't help me.

const specs = 
[ 
  { label: 'Brand', value: 'Nike' },
  { label: 'Age range', value: '8 to 13' },
  { label: 'Age range', value: '14+' }
 ]

I want to skip the "Brand", which works with my code, and I want that if there are multiple objects with the same label, they need to be merged in a unique object which contains that label and ALL of the values together, so the output will have brand removed and the other values merged:

[
  { label: 'Age range', value: '8 to 13 - 14+' }
 ]

Here's my code:

 var newSpecs = []

    for (let x = 0; x < specs.length; x++) {
      if (specs[x].label === 'Brand') continue

      for (let j = x + 1; j < specs.length; j++) {
        if (specs[x].label === specs[j].label) {
          specs[x].value += ' - ' + specs[j].value
        }
      }
      newSpecs.push({ label: specs[x].label, value: specs[x].value })
    }
    return newSpecs

But this simply does not work, it created multiple merged age range. I tried another time by using delete and other things but got me "cannot read label of undefine", so I'll keep this way, but I cannot figure out how to do it

5
  • Does this answer your question? How can i return two objects in javascript Commented Dec 28, 2020 at 12:22
  • Your code seems correct. Could you show the value that newSpecs returns? Commented Dec 28, 2020 at 12:24
  • [ { label: 'Age range', value: '8 to 13 - 14+' }, { label: 'Age range', value: '14+' } ] @MRMarkII Commented Dec 28, 2020 at 12:26
  • You can take a look here Commented Dec 28, 2020 at 12:29
  • Oh, right. You need to create a string, and concat all the values in it. So when you finish the for, you can choose any label (index 1 for example, because if you choose 0 is brand) and put the string that you created in the for in the value. Commented Dec 28, 2020 at 12:29

2 Answers 2

0

You receive multiple "Age range" because you have nested loops. Try this approach using .reduce() for grouping:

const specs = [ 
  { label: 'Brand', value: 'Nike' },
  { label: 'Age range', value: '8 to 13' },
  { label: 'Age range', value: '14+' }
];

var newSpecs = specs.reduce((res, curr) => {
  if (curr.label === 'Brand') return res;
  
  var group = res.find((el) => el.label === curr.label);
  if (group) {
    group.value += ' - ' + curr.value;
  } else {
    res.push(curr);
  }

  return res;
}, []);

console.log(newSpecs);

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

Comments

0

You can use map to separate out labels

const specs = [
  { label: "Brand", value: "Nike" },
  { label: "Age range", value: "8 to 13" },
  { label: "Age range", value: "14+" },
];
const labelMap = {};
specs.forEach((sp) => {
  if (sp.label !== "Brand") {
    labelMap[sp.label] = labelMap[sp.label] || { label: sp.label, value: [] };
    labelMap[sp.label].value.push(sp.value);
  }
});
const op = Object.values(labelMap).map((el) => ({
  ...el,
  value: el.value.join(" - "),
}));
console.log(op);

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.