Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

144
Visualizações
React-Native | Generate a non-repeating (name) generator in React-Native

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,
  },
});
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

if I understand you want to select without return

let arr1 = ['a', 'b', 'c'];
let value;

Option1: Copy the array to temp array

let arr2 = [...arr1];
let random_index = Math.floor(Math.random() * arr2.length);
value = arr2[random_index];
arr2 = arr2.filter((val, index) => index !== random_index);

if (arr2.length === 0)
    arr2 = [...arr1];

Option2: Save the indexes of the array

let arr2 = Array.from(Array(arr1.length).keys());
let random_index = Math.floor(Math.random() * arr2.length);
value = arr1[arr2[random_index]];
arr2 = arr2.filter((val, index) => index !== random_index);

if (arr2.length === 0)
    arr2 = Array.from(Array(arr1.length).keys());
about 4 years ago · Juan Pablo Isaza Relatório

0

Option 1: Quick and Easy

Create an object in state to track the used name IDs.

const [usedIds, setUsedIds] = useState([]);

Then update the findLinkByName function to use this array. You should also invoke the random number generator inside the function.

function findLinkByName() {
  // clear array if full
  if(usedIds.length === differentNames.namesContainer.names.length) {
    setUsedIds([]);
  }

  // find unique ID
  let randomId;
  do {
    randomId = RandomNumber(1,5);
  } while(usedIds.includes(randomId));
  
  // add used ID to array
  setUsedIds(prev => [...prev, randomId]);

  // return random name
  return differentNames.namesContainer.names.find(n => n.id === randomId);
}

Option 2: Move Names to State

You can also simply append a used property to each name object in the name container and change it to be stored in state so that we can mutate it. The ugliest part of this is that the names are kept 3 levels deep in the object. If that can be lifted up, then the following statements could be much shorter.

const [names, setNames] = useState({
  namesContainer: {
    names: [
      { name: "(1) Sophie", id: 1, used: false },
      { name: "(2) Emma", id: 2, used: false },
      { name: "(3) Lisa", id: 3, used: false },
      { name: "(4) Esmée", id: 4, used: false },
      { name: "(5) Zoe", id: 5, used: false },
    ],
  },
});

I'd also recommend using const and let over var for various reasons 😉

Then your findLinkByName function can be updated to work much more efficiently like this:

function findLinkByName() {
  // clear array if full
  if(names.namesContainer.names.filter(n => !n.used).length === 0) {
    let newNames = {...names};
    newNames.namesContainer.names.map(n => {...n, used: false});
    setNames(newNames);
  }

  // find random ID
  const unusedNames = names.filter(n => !n.unsed);
  const randId = Math.floor(Math.random() * unusedNames.length);
  
  // update state
  let newNames = {...names};
  newNames.namesContainer.names.map(n => {
    return (n.id === randId) ? {...n, used: true} : {...n}
  });
  setNames(newNames);

  // return random name
  return names.namesContainer.names.find(n => n.id === randId);
}
about 4 years ago · Juan Pablo Isaza Relatório

0

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.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda