3

I'm building my first react-native app and I want to show user some screen of his "followers" separated by categories but to do it I think I have to create new array of objects from this what I have.

I have array of objects like this:

followers: [
    {
      userId: 2,
      userName: "Abigail",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "A"
    },
    {
      userId: 3,
      userName: "John",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "B"
    },
    {
      userId: 4,
      userName: "Bob",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "A"
    },
    {
      userId: 5,
      userName: "Martha",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "B"
    } 
]

And now I would like to render these followers to user separated by categories that are in followers array objects. So I think I need to create new array of objects and I think it should looks like this:

followersSortedByCategory = [
      {
        category: "A",
        followers: [
          {
            userId: 2,
            userName: "Abigail",
            followDate: "1980-04-09T10:15:30+07:00",
            category: "A"
          },
          {
            userId: 4,
            userName: "Bob",
            followDate: "1980-04-09T10:15:30+07:00",
            category: "A"
          }
        ]
      },
      {
        category: "B",
        followers: [
          {
            userId: 3,
            userName: "John",
            followDate: "1980-04-09T10:15:30+07:00",
            category: "B"
          },
          {
            userId: 5,
            userName: "Martha",
            followDate: "1980-04-09T10:15:30+07:00",
            category: "B"
          }
        ]
      }
    ]

I'm not sure how to do this without many "if's". I think there is a good way to do it using map, filter etc. functions but I don't know how.

0

4 Answers 4

4

Shorter solution:

const followers = [
{
  userId: 2,
  userName: "Abigail",
  followDate: "1980-04-09T10:15:30+07:00",
  category: "A"
},
{
  userId: 3,
  userName: "John",
  followDate: "1980-04-09T10:15:30+07:00",
  category: "B"
},
{
  userId: 4,
  userName: "Bob",
  followDate: "1980-04-09T10:15:30+07:00",
  category: "A"
},
{
  userId: 5,
  userName: "Martha",
  followDate: "1980-04-09T10:15:30+07:00",
  category: "B"
} 
]

function formatFollowers(followers){
  const categories = [...new Set(followers.map(follower=> follower.category))]
   return categories.reduce((acc, category)=> {
     const _followers = followers.filter(follower=> follower.category === category)
    return [...acc, {category: category, followers: _followers}]
  }, [])
}

console.log(formatFollowers(followers))

EDIT: on @Kinglish's request, here is the explanation of the code:

a) I loop over the followers array and only keep the category names. I also make sure to remove all potential duplicates thanks to new Set(). The result will look like this: const categories = ["A", "B"].

b) I loop over the categories array. For each category, I fetch all matching followers. Then, I push the formatted result in the final array.

c) output is properly formatted.

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

Comments

2

const followers = [
  { userId: 2, userName: "Abigail", followDate: "1980-04-09T10:15:30+07:00", category: "A" },
  { userId: 3, userName: "John", followDate: "1980-04-09T10:15:30+07:00", category: "B" },
  { userId: 4, userName: "Bob", followDate: "1980-04-09T10:15:30+07:00", category: "A" },
  { userId: 5, userName: "Martha", followDate: "1980-04-09T10:15:30+07:00", category: "B" } 
];

const followersSortedByCategory = [...
  // iterate over followers array while updating categoryMap (category-records)
  followers.reduce((categoryMap, follower) => {
    const { category } = follower;
    // get record of follower's category if exists
    const categoryRecord = categoryMap.get(category);
    if(!categoryRecord) { // if not, add new pair
      categoryMap.set(category, { category, followers: [follower] });
    } else { // else update the record's followers array
      categoryRecord.followers.push(follower);
    }
    return categoryMap;
  }, new Map)
  // return grouped list by categories
  .values()
];

console.log(followersSortedByCategory);

Comments

1

All these answers probably will use reduce, and they're all probably as good as each other. But they all use subtly different approaches to the data iteration. This approach uses object keys

let categories = Object.values(
// the final output will be an array
    data.followers.reduce( (b,a) => {
    // we iterate the followers and build the accumulator object
    if (b.hasOwnProperty(a.category)) b[a.category].followers.push(a)
    // if our accumulating object already has the category key, add to the follower array
    else b[a.category] = {category: a.category, followers: [a]}
    // otherwise create the object key and initialize it with the first follower
    return b
    },{}))

let data = {
  followers :[
  { userId: 2, userName: "Abigail", followDate: "1980-04-09T10:15:30+07:00", category: "A" },
  { userId: 3, userName: "John", followDate: "1980-04-09T10:15:30+07:00", category: "B" },
  { userId: 4, userName: "Bob", followDate: "1980-04-09T10:15:30+07:00", category: "A" },
  { userId: 5, userName: "Martha", followDate: "1980-04-09T10:15:30+07:00", category: "B" } 
]}

let categories = Object.values(data.followers.reduce( (b,a) => {
if (b.hasOwnProperty(a.category)) b[a.category].followers.push(a)
else b[a.category] = {category: a.category, followers: [a]}
return b
},{}))

console.log(categories)

Comments

0

You can use lodash for this

const sortFollowers = ((followers) => {
  const grouped = _.groupBy(followers, 'category');
  console.log(grouped);
});

const followers = [{ userId: 2, userName: "Abigail", followDate: "1980-04-09T10:15:30+07:00", category: "A" }, { userId: 3, userName: "John", followDate: "1980-04-09T10:15:30+07:00", category: "A" }, { userId: 4, userName: "Bob", followDate: "1980-04-09T10:15:30+07:00", category: "A" }, { userId: 5, userName: "Martha", followDate: "1980-04-09T10:15:30+07:00", category: "B" }];

sortFollowers(followers);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

import "./styles.css";
import { _ } from "lodash";

const sortFollowers = ((followers) => {
  const grouped = _.groupBy(followers, 'category');
  console.log(grouped);
});

export default function App() {

  const followers = [
    {
      userId: 2,
      userName: "Abigail",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "A"
    },
    {
      userId: 3,
      userName: "John",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "A"
    },
    {
      userId: 4,
      userName: "Bob",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "A"
    },
    {
      userId: 5,
      userName: "Martha",
      followDate: "1980-04-09T10:15:30+07:00",
      category: "B"
    } 
  ];

  sortFollowers(followers);
  
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.