Home > database >  Getting unique values from an Array for use in ListItem
Getting unique values from an Array for use in ListItem

Time:02-08

I have an array of objects that contains the location of each user. I'm trying to group them by location and use that as the title in my react native component but I'm having difficulty filtering on the location property and could use a push in the right direction.

Here's a sample of the array:

const Users = [
    {
        id: 1,
        name: "user1",
        image: require("../assets/1.jpeg"),
        location: "Portland"
    },
    {
        id: 2,
        name: "user2",
        image: require("../assets/2.jpeg"),
        location: "Portland"
    },
    {
        id: 3,
        name: "user3",
        image: require("../assets/3.jpeg"),
        location: "New York"
    },
    {
        id: 4,
        name: "user4",
        image: require("../assets/4.jpeg"),
        location: "Pullman"
    },
    {
        id: 5,
        name: "user5",
        image: require("../assets/5.jpeg"),
        location: "Portland"
    },
    {
        id: 6,
        name: "user6",
        image: require("../assets/6.jpeg"),
        location: "San Francisco"
    },
    {
        id: 7,
        name: "user7",
        image: require("../assets/7.jpeg"),
        location: "Pullman"
    },
];

This is the component. I've tried both filter and reduce methods but I get the same duplicate results because it's evaluating the entire object. I want to return only the unique values of the location property.

const userItems = ({ item }) => {
    return (
        <>
            <ThemeProvider theme={ListItemTheme}>
                <View>
                    {Users.filter(
                        (currentValue, index, arr) => arr.indexOf(currentValue) === index
                    ).map((user) => (
                        <View style={styles.userContainer}>
                            <ListItem.Title key={user.id}>{user.location}</ListItem.Title>
                        </View>
                    ))}
                </View>
            </ThemeProvider>
        </>
    );
};

try with reduce method.

const userItems = ({ item }) => {
    return (
        <>
            <ThemeProvider theme={ListItemTheme}>
                <View>
                    {Users.reduce(
                        (acc, currentValue) =>
                            acc.includes(currentValue.location)
                                ? acc
                                : [...acc, currentValue],
                        []
                    ).map((user) => (
                        <View style={styles.userContainer}>
                            <ListItem.Title key={user.id}>{user.location}</ListItem.Title>
                        </View>
                    ))}
                </View>
            </ThemeProvider>
        </>
    );
};

CodePudding user response:

Edit I misunderstood the question, I would suggest using reduce.

note I made all require statements a string for this example to run

const Users = [{
    id: 1,
    name: "user1",
    image: 'require("../assets/1.jpeg")',
    location: "Portland"
  },
  {
    id: 2,
    name: "user2",
    image: 'require("../assets/2.jpeg")',
    location: "Portland"
  },
  {
    id: 3,
    name: "user3",
    image: 'require("../assets/3.jpeg")',
    location: "New York"
  },
  {
    id: 4,
    name: "user4",
    image: 'require("../assets/4.jpeg")',
    location: "Pullman"
  },
  {
    id: 5,
    name: "user5",
    image: 'require("../assets/5.jpeg")',
    location: "Portland"
  },
  {
    id: 6,
    name: "user6",
    image: 'require("../assets/6.jpeg")',
    location: "San Francisco"
  },
  {
    id: 7,
    name: "user7",
    image: 'require("../assets/7.jpeg")',
    location: "Pullman"
  },
];

console.log(Users.reduce((acc, val) => {
  acc[val.location] = acc[val.location] ? [...acc[val.location], val] : [val];
  return acc
}, {}))

And something like this in the component?

const userItems = ({ item }) => {
 const users = Users.reduce((acc, val) => {
      acc[val.location] = acc[val.location] ? [...acc[val.location], val] : [val];
      return acc
    }, {})

    return (
     <>
      <ThemeProvider theme={ListItemTheme}>
         <View>
          {Object.keys(users).map((key) => (         
           <View style={styles.userContainer}>
             {users[key].map((user) => (
             <ListItem.Title key={user.id}>{key}</ListItem.Title>
             // >>>.....more user info stuff
             ))}
           </View>
           ))}   
         </View>
      </ThemeProvider>
    </>
    );
};
  •  Tags:  
  • Related