Hi everyone!
I have a question that I hope you can help me with. I just started with React Native and I’m working on a simple name generator.
I have an array with different names in it. When I click on the button, a random number is generated. This number is associated with the array’s list of names.
This all works, but I’m getting duplicate names. I would like to go through the whole list without there being a duplicate name. When all names have been passed, the list starts again.
I was thinking of making a separate array that keeps track of the numbers that have passed. And then exclude those numbers. But I’m not sure how to add this and if this is the right way.
See below my code. Apologies if this is a bit messy or cumbersome.
import React, { useState } from "react"; import { StyleSheet, Text, View, Button } from "react-native"; export default function GirlScreen() { const RandomNumber = (min, max) => { return Math.floor(Math.random() * (max - min + 1) + min); }; const [count, setCount] = useState(0); const onPress = () => { setCount(RandomNumber(1, 100)); }; const random = RandomNumber(1, 5); var differentNames = { namesContainer: { names: [ { name: "(1) Sophie", id: 1 }, { name: "(2) Emma", id: 2 }, { name: "(3) Lisa", id: 3 }, { name: "(4) Esmée", id: 4 }, { name: "(5) Zoe", id: 5 }, ], }, }; function findLinkByName(random) { for (const item of differentNames.namesContainer.names) { if (item.id === random) { return item.name; } } } return ( <View style={styles.countContainer}> <Text style={styles.name}>{findLinkByName(random)}</Text> <Button onPress={onPress} title="Next Name" /> </View> ); } const styles = StyleSheet.create({ countContainer: { flex: 1, alignItems: "center", justifyContent: "center", }, name: { color: "black", fontSize: 30, }, });
Advertisement
Answer
You could keep track of two states. One holds already selectedNames
and the other one holds still availableNames
as follows.
const [selectedNames, setSelectedNames] = useState([]) const [availableNames, setAvailableNames] = useState([ { name: "(1) Sophie", id: 1 }, { name: "(2) Emma", id: 2 }, { name: "(3) Lisa", id: 3 }, { name: "(4) Esmée", id: 4 }, { name: "(5) Zoe", id: 5 }, ])
Then, we choose a random number between 0
and the length of avialableNames
which represents the index we want to pick from avialableNames
.
const random = RandomNumber(0, availableNames.length - 1);
Then, your onPress
function looks as follows.
const onPress = () => { setAvailableNames(availableNames.filter(n => n !== availableNames[random])) setSelectedNames([...selectedNames, availableNames[random]]) };
We add the new randomly picked name to selectedNames
and remove it from availableNames
at the same time.
Your findLinkByName
function could look as follows.
function findLinkByName(random) { if (availableNames.length === 0) { setAvailableNames(selectedNames.sort((a, b) => a.id - b.id)) setSelectedNames([]) return availableNames[0] } return availableNames[random].name }
As long as there are names in availableNames
, that is its length is not equal to 0
, we just pick it and return its name. If all avialable names have been selected, we reset the states, sort the selectedNames by their id prop and return the first name of the list again.
Here is a working snack.