为什么随机播放在React中不起作用?

时间:2018-06-19 20:31:15

标签: javascript node.js reactjs

我有来自JSON对象的数据,每个项目都包含一个问题和一个答案,我需要设置2个状态项目:1是原始数组,1是随机排列的数组,然后稍后将其呈现。

但是,即使我的随机播放功能有效,我的questionsanswers也是相同的。

constructor(props) {
    super(props)
    this.shuffleData = this.shuffleData.bind(this)
    this.state = {
        questions: [],
        answers: []
    }
}

shuffleData = data => {
    let i = data.length - 1
    while (i > 0) {
        const   j = Math.floor(Math.random() * (i + 1)),
                temp = data[i]
        data[i] = data[j]
        data[j] = temp
        i--
    }
    return data
}

componentDidMount() {
    API.getQuesitons()
    .then(res => {
        const   questions = res.data, // [{question: 'some question', answer: 'some answer'}, {}, ...]
                answers = this.shuffleData(questions)
        this.setState({questions, answers})

        console.log(this.state) // both questions and answers are the same
    })
}

为方便起见,我在这里有一个虚拟JSON对象:

[
    {_id: '1', question: 'q1', answer: 'a1'},
    {_id: '2', question: 'q2', answer: 'a2'},
    {_id: '3', question: 'q3', answer: 'a3'},
    {_id: '4', question: 'q4', answer: 'a4'},
    {_id: '5', question: 'q5', answer: 'a5'},
]

3 个答案:

答案 0 :(得分:2)

您正在将数组的引用发送到shuffle函数。通过这样做,您正在修改原始数组,而不是其副本。因此,最后,您只得到了两个变量引用的随机排列的数组。
尝试更改此内容:
answers = this.shuffleData(questions)
为此:
answers = this.shuffleData([...questions])
这将在重排数组之前对其进行克隆。

答案 1 :(得分:1)

您只是就地对问题数组进行洗牌。

前后数组相同

您可以执行以下操作:

const   questions = res.data, // [{question: 'some question', answer: 'some answer'}, {}, ...]
        answers = this.shuffleData([].concat(questions))

您的洗牌也很差。原因是在每个索引上选择相同随机索引的机会非常高,并且当您遍历数组时,机会增加。例如在索引4处,您有20%的机会将索引4的内容与自身交换-即。不变。在索引3处,您有25%的机会不变。在2时有33%不变的机会。在1时有50%的机会没有变化,在0时有100%的机会没有变化。

更好的方法是简单地随机交换:

for(var i = 0; i< data.length; i++){
    var rand = Math.floor(Math.random()* (data.length));
    var tmp = data[i];
    data[i] = data[rand];
    data[rand] = tmp;
 }

答案 2 :(得分:0)

看起来您是在对数组中的整个对象进行改组,而不是对其中的实际问题/答案键进行改组。以下实现了我认为您想要的:

shuffleData = data => {
    let i = data.length - 1
    while (i > 0) {
        const j = Math.floor(Math.random() * (i + 1)),
            temp = data[i].answer
        data[i].answer = data[j].answer
        data[j].answer = temp
        i--
        console.log(data)
    }
    return data
}

let myArr = [
    {_id: '1', question: 'q1', answer: 'a1'},
    {_id: '2', question: 'q2', answer: 'a2'},
    {_id: '3', question: 'q3', answer: 'a3'},
    {_id: '4', question: 'q4', answer: 'a4'},
    {_id: '5', question: 'q5', answer: 'a5'},
];

console.log(shuffleData(myArr));