2

So suppose my array looks like this:

let langArr = [
     ["python", "blue"]
    ,["python", "blue"]
    ,["c++", "red"]
    ,["java", "yellow"]
    ,["javascript", "lime"]
    ,["shell", "green"]
    ,["c++", "red"]
];

what I want is something like this:

{
  python: {
    count: 2
    color: "blue"
  }
  c++: {
    count: 2
    color: "red"
  }
  java: {
    count: 1
    color: "yellow"
  }
  and so on...
}

I tried reduce method like this:

let langCount = langArr.reduce((lang, [name, color]) => {
      lang[name] = (lang[name] || 0) + 1;
      lang[color] = 'color';
      return lang;
    }, {});
    console.log(langCount);

but I get this output:

{
  python: 2
  blue: "color"
  c++: 2
  red: "color"
  java: 1
  yellow: "color"
  and so on...
}
5
  • What have you tried to modify the .reduce() snippet so it produces the output you're expecting? Commented Mar 9, 2020 at 15:29
  • You lack creation of the sub-objects, and one indirection in the reduce code. Most notably, the word count never occurs in your code, which should make the primary issue obvious - if you had a place to put that, you'd (probably) have the desired structure. Commented Mar 9, 2020 at 15:30
  • @Andreas that is what I tried, I don't know how to get them into separate objects Commented Mar 9, 2020 at 15:32
  • what happens if you have different colors for a language? Commented Mar 9, 2020 at 15:35
  • But you know how to use destructuring? Commented Mar 9, 2020 at 15:39

2 Answers 2

1

You need an object for each language.

This approach takes an object as default value if lang[name] is falsy, like undefined.

The pattern

variable = variable || value;

works with a logical OR ||:

  • if variable has a truthy value, take this value,
  • if variable has a falsy value, take value instead.

let langArr = [["python", "blue"], ["python", "blue"], ["c++", "red"], ["java", "yellow"], ["javascript", "lime"], ["shell", "green"], ["c++", "red"]],
    langCount = langArr.reduce((lang, [name, color]) => {
        lang[name] = lang[name] || { count: 0, color };
        lang[name].count++;
        return lang;
    }, {});

console.log(langCount);

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

2 Comments

This is just another "group by" answer (with the little twist, that it's not an array with all options but a number for the count). This is now already enough for a new answer instead of a dupe-vote?
Thank you so much! can you also please explain what this line does lang[name] = lang[name] || { count: 0, color };
0

You can use this:

array.reduce((acc, current) => {
        if(!acc.hasOwnProperty(current[0])){
            acc[current[0]] = {count: 0, color: current[1]};
        }
        acc[current[0]].count += 1;
        return acc;
    }, {});

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.