大家好!
我有一個問題希望你能幫助我。我剛開始使用 React Native,我正在開發一個簡單的名稱生成器。
我有一個不同名稱的陣列。當我點擊按鈕時,會生成一個亂數。此數字與陣列的名稱串列相關聯。
這一切都有效,但我得到了重復的名字。我想瀏覽整個串列而沒有重復的名稱。當所有名稱都通過后,串列重新開始。
我正在考慮制作一個單獨的陣列來跟蹤已通過的數字。然后排除這些數字。但我不確定如何添加它以及這是否是正確的方法。
請參閱下面我的代碼。抱歉,如果這有點混亂或麻煩。
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,
},
});
uj5u.com熱心網友回復:
您可以跟蹤兩種狀態。一個已經持有selectedNames,另一個仍然持有availableNames如下。
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 },
])
然后,我們選擇一個介于 和 之間的亂數0,其長度avialableNames代表我們要從中選擇的索引avialableNames。
const random = RandomNumber(0, availableNames.length - 1);
然后,您的onPress函式如下所示。
const onPress = () => {
setAvailableNames(availableNames.filter(n => n !== availableNames[random]))
setSelectedNames([...selectedNames, availableNames[random]])
};
selectedNames我們同時添加和洗掉新隨機選擇的名稱availableNames。
您的findLinkByName函式可能如下所示。
function findLinkByName(random) {
if (availableNames.length === 0) {
setAvailableNames(selectedNames.sort((a, b) => a.id - b.id))
setSelectedNames([])
return availableNames[0]
}
return availableNames[random].name
}
只要 中有名字availableNames,也就是它的長度不等于0,我們就選擇它并回傳它的名字。如果所有可用的名稱都已被選中,我們重置狀態,按其 id 屬性對 selectedNames 進行排序,并再次回傳串列的第一個名稱。
這是一份作業零食。
uj5u.com熱心網友回復:
如果我了解您想選擇不回傳
let arr1 = ['a', 'b', 'c'];
let value;
選項1:將陣列復制到臨時陣列
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];
選項2:保存陣列的索引
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());
uj5u.com熱心網友回復:
選項 1:快速簡便
在 state 中創建一個物件以跟蹤使用的名稱 ID。
const [usedIds, setUsedIds] = useState([]);
然后更新 findLinkByName 函式以使用此陣列。您還應該在函式內部呼叫亂數生成器。
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);
}
選項 2:將名稱移至州
您還可以簡單地將used屬性附加到名稱容器中的每個名稱物件,并將其更改為存盤在狀態中,以便我們可以對其進行變異。最丑陋的部分是名稱在物件中保留了 3 層。如果可以將其提升,那么以下陳述句可能會更短。
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 },
],
},
});
我還建議 出于各種原因const 使用and let over ??var
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);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/433501.html
標籤:javascript 反应 反应式
