DEV Community

Ganesh Shetty
Ganesh Shetty

Posted on • Edited on

How to convert an array into a specific format in Javascript?

  const endorsedSkills = [
        {
            language: "Javascript",
            user: 'Aarav'
        },
        {
            language: "ReactJS",
            user: 'Aarush'
        },
        {
            language: "Javascript",
            user: 'Aaryan'
        },
        {
            language: "ReactJS",
            user: 'Aayansh'
        },
        {
            language: "Angular",
            user: 'Aayush'
        },
        {
            language: "Javascript",
            user: 'Aayansh'
        },
        {
            language: "Angular",
            user: 'Adhrit'
        },
        {
            language: "Javascript",
            user: 'Adi'
        },
        {
            language: "ReactJS",
            user: 'Pranav'
        },
    ];

Enter fullscreen mode Exit fullscreen mode

We are given an array which contains list of objects where each one of them represents a language and user it was endorsed by.

If we have to modify this array by grouping them by language so that we can display list of languages with endorsed by users list and count in our UI,So output would be something like this

  [
        {
            "language": "Javascript",
            "user": [
                "Aarav",
                "Aaryan",
                "Aayansh",
                "Adi"
            ],
            "count": 4
        },
        {
            "language": "ReactJS",
            "user": [
                "Aarush",
                "Aayansh",
                "Pranav"
            ],
            "count": 3
        },
        {
            "language": "Angular",
            "user": [
                "Aayush",
                "Adhrit"
            ],
            "count": 2
        }
    ]
Enter fullscreen mode Exit fullscreen mode

How do we do it efficiently without any external libraries?

Answer is by using Array.reduce() method.reduce method is very useful in scenario like this.

Basic idea behind this is very simple, We keep an empty array as an accumulator, While iterating over each element of an array we check if element is already present if yes, then we update existing item with that particular index value if no, then we create a new item

 const formattedArray = endorsedSkills.reduce((acc, cur) => {
        const index = acc.findIndex((ele) => ele.language == cur.language);
        if (index != -1) {
            acc[index].user.push(cur.user);
            acc[index].count++;
        } else {
            acc.push({ language: cur.language, user: [cur.user], count: 1 });
        }
        return acc;
    }, []);
    console.log('formattedArray', formattedArray);
Enter fullscreen mode Exit fullscreen mode

Hope this helps someone who is looking for something similar.

Top comments (2)

Collapse
 
peerreynders profile image
peerreynders • Edited
const toLanguage = ({ language }) => language;
const toUser = ({ user }) => user;
const toLanguageUsers = ([language, group]) => {
  const user = group.map(toUser);
  return {
    language,
    user,
    count: user.length,
  };
};

const formattedArray = Object.entries(endorsedSkills.groupBy(toLanguage)).map(
  toLanguageUsers
);
console.log(formattedArray);
Enter fullscreen mode Exit fullscreen mode

Or the less readable version

const formattedArray = Object.entries(
  endorsedSkills.groupBy(({ language }) => language)
).map(([language, group]) => {
  const user = group.map(({ user }) => user);
  return {
    language,
    user,
    count: user.length,
  };
});
console.log(formattedArray);
Enter fullscreen mode Exit fullscreen mode

MDN: Array.prototype.groupBy()

Array Grouping Proposal

Currently at Stage 3

Currently polyfilled by core-js or perhaps something like

function groupBy(array, toKey) {
  const groupElement = (groups, element) => {
    const key = toKey(element);

    if (Object.hasOwn(groups, key)) groups[key].push(element);
    else groups[key] = [element];

    return groups;
  };

  return array.reduce(groupElement, {});
}

const toLanguage = ({ language }) => language;
const toUser = ({ user }) => user;
const toLanguageUsers = ([language, group]) => {
  const user = group.map(toUser);
  return {
    language,
    user,
    count: user.length,
  };
};

const formattedArray = Object.entries(groupBy(endorsedSkills, toLanguage)).map(
  toLanguageUsers
);
console.log(formattedArray);
Enter fullscreen mode Exit fullscreen mode

to be replaced later.

Collapse
 
iainsimmons profile image
Iain Simmons

I'm looking forward to this one being better supported!