0

I have an array with objects like below,

var users = [{
    id: 1,
    name: 'Swamy',
    category_id: 1,
    category_name: "Male"
  },
  {
    id: 2,
    name: 'Mahesh',
    category_id: 1,
    category_name: "Male"
  },
  {
    id: 3,
    name: 'Kajal',
    category_id: 2,
    category_name: "Female"
  },
  {
    id: 4,
    name: 'Rasi',
    category_id: 2,
    category_name: "Female"
  }
]

I want to re arrange the above based on category

var cat_users = [{
    category_id: 1,
    category_name: "Male",
    users: [{
      id: 1,
      name: 'Swamy'
    }, {
      id: 2,
      name: 'Mahesh'
    }]
  },
  {
    category_id: 2,
    category_name: "Female",
    users: [{
      id: 3,
      name: 'Kajal'
    }, {
      id: 4,
      name: 'Rasi'
    }]
  },
]

I am looking for a solution and cannot seem to find anything related. Please help in rearranging the array.

2
  • Array comes with a sort function, to which you can provide a function for a custom compare. Example here. Commented Oct 14, 2020 at 1:46
  • Search for "group by" and you'll find lots of similar questions. Commented Oct 14, 2020 at 1:48

2 Answers 2

1

You have to find if the category_id exists in your sorted array. If not then push a new entry. If yes then add the user to the users of that entry.

interface User {
    id: number;
    name: string;
};

interface Category {
    category_id: number;
    category_name: string;
}

interface Entry extends User, Category { }

interface SortedEntry extends Category {
    users: Array<User>;
}

var users: Array<Entry> = [
    {
        id: 1,
        name: 'Swamy',
        category_id: 1,
        category_name: "Male"
    },
    {
        id: 2,
        name: 'Mahesh',
        category_id: 1,
        category_name: "Male"
    },
    {
        id: 3,
        name: 'Kajal',
        category_id: 2,
        category_name: "Female"
    },
    {
        id: 4,
        name: 'Rasi',
        category_id: 2,
        category_name: "Female"
    }
];

const sorted: Array<SortedEntry> = [];

for (const { id, name, category_name, category_id } of users) {
    const match = sorted.find((entry) => entry.category_id === category_id);
    if (!match) {
        sorted.push({
            category_id,
            category_name,
            users: [
                {
                    id,
                    name,
                }
            ]
        });
    }
    else {
        match.users.push({
            id,
            name,
        });
        const index = sorted.indexOf(match);
        sorted[index] = match;
    }
}

console.log(sorted);
Sign up to request clarification or add additional context in comments.

Comments

1

First, based on input, you can group that input by category_id using Array.reduce.

And from that groupedBy object, you can generate the result you want using Array.map.

var users = [{
    id: 1,
    name: 'Swamy',
    category_id: 1,
    category_name: "Male"
  },
  {
    id: 2,
    name: 'Mahesh',
    category_id: 1,
    category_name: "Male"
  },
  {
    id: 3,
    name: 'Kajal',
    category_id: 2,
    category_name: "Female"
  },
  {
    id: 4,
    name: 'Rasi',
    category_id: 2,
    category_name: "Female"
  }
];

const groupBy = users.reduce((acc, cur) => {
  acc[cur.category_id] ? acc[cur.category_id].users.push({
    id: cur.id,
    name: cur.name
  }) : acc[cur.category_id] = {
    category_id: cur.category_id,
    category_name: cur.category_name,
    users: [{
      id: cur.id,
      name: cur.name
    }]
  };
  return acc;
}, {});

const result = Object.entries(groupBy).map(([ category_id, rest ]) => ({
  category_id,
  ...rest
}));
console.log(result);

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.