为什么当我改变状态时排序不能正常工作?
Why doesn't sorting work correctly when I change state?
我有 BubbleSort 组件,但是当我开始排序过程时出现问题,我的排序不正确。我敢肯定,算法本身是正确编写的。我想设置状态过程有问题,但无法弄清楚它可能是什么。
import React, {Component} from "react";
import ArrayView from "../ArrayView/ArrayView";
export default class BubbleSort extends Component{
state = {
elements: this.props.elements
}
sort = () => {
const length = this.state.elements.length;
for (let i = 0; i < length; i++) {
for (let j = i + 1; j < length; j++) {
if (this.state.elements[i].value > this.state.elements[j].value) {
this.swap(i, j);
}
}
}
}
swap = (first, second) => {
this.setState((state) => {
const newElements = [...state.elements];
const temp = newElements[first];
newElements[first] = newElements[second];
newElements[second] = temp;
return {
elements: newElements
}
})
}
render() {
const { elements } = this.state;
return (
<ArrayView elements={elements} onSort={this.sort} />
)
}
}
问题是您每次都在交换状态中的元素,而不是在您实际排序的数组中交换它们 sort
(本地 elements
数组)。所以后续对 sort
中的局部 elements
数组的操作继续使用旧值,这意味着冒泡排序将无法正常工作。
除非您希望您的组件在每次交换时更新 DOM(这意味着对其进行重大更改),否则只需更改状态一次,在完成排序后设置新数组。
您不需要在交换功能中设置新状态。
交换元素并在排序函数中设置新状态,如下所示:
sort = () => {
const elements = [...this.state.elements];
const length = elements.length;
for (let i = 0; i < length; i++) {
for (let j = i + 1; j < length; j++) {
if (elements[i].value > elements[j].value) {
const temp = elements[i];
elements[i] = elements[j];
elements[j] = temp;
}
}
}
this.setState({ elements });
}
由于您想逐步显示排序过程,您可以在交换后的每个状态更新之间添加延迟,使用 Promise
和 async-await
语法。
在BubbleSort
组件中,添加如下两个函数:
在交换操作后的每个状态更新之间添加延迟
sleep(seconds) {
return new Promise((resolve, reject) => {
setTimeout(resolve, seconds * 1000);
});
};
在嵌套循环内的每个交换操作后将调用 sleep()
函数的排序函数
async sort() {
const elements = [...this.state.elements];
const length = elements.length;
for (let i = 0; i < length; i++) {
for (let j = i + 1; j < length; j++) {
if (this.state.elements[i].value > this.state.elements[j].value) {
const temp = elements[i];
elements[i] = elements[j];
elements[j] = temp;
this.setState({ elements });
await this.sleep(1.5);
}
}
}
};
演示:
我有 BubbleSort 组件,但是当我开始排序过程时出现问题,我的排序不正确。我敢肯定,算法本身是正确编写的。我想设置状态过程有问题,但无法弄清楚它可能是什么。
import React, {Component} from "react";
import ArrayView from "../ArrayView/ArrayView";
export default class BubbleSort extends Component{
state = {
elements: this.props.elements
}
sort = () => {
const length = this.state.elements.length;
for (let i = 0; i < length; i++) {
for (let j = i + 1; j < length; j++) {
if (this.state.elements[i].value > this.state.elements[j].value) {
this.swap(i, j);
}
}
}
}
swap = (first, second) => {
this.setState((state) => {
const newElements = [...state.elements];
const temp = newElements[first];
newElements[first] = newElements[second];
newElements[second] = temp;
return {
elements: newElements
}
})
}
render() {
const { elements } = this.state;
return (
<ArrayView elements={elements} onSort={this.sort} />
)
}
}
问题是您每次都在交换状态中的元素,而不是在您实际排序的数组中交换它们 sort
(本地 elements
数组)。所以后续对 sort
中的局部 elements
数组的操作继续使用旧值,这意味着冒泡排序将无法正常工作。
除非您希望您的组件在每次交换时更新 DOM(这意味着对其进行重大更改),否则只需更改状态一次,在完成排序后设置新数组。
您不需要在交换功能中设置新状态。
交换元素并在排序函数中设置新状态,如下所示:
sort = () => {
const elements = [...this.state.elements];
const length = elements.length;
for (let i = 0; i < length; i++) {
for (let j = i + 1; j < length; j++) {
if (elements[i].value > elements[j].value) {
const temp = elements[i];
elements[i] = elements[j];
elements[j] = temp;
}
}
}
this.setState({ elements });
}
由于您想逐步显示排序过程,您可以在交换后的每个状态更新之间添加延迟,使用 Promise
和 async-await
语法。
在BubbleSort
组件中,添加如下两个函数:
在交换操作后的每个状态更新之间添加延迟
sleep(seconds) { return new Promise((resolve, reject) => { setTimeout(resolve, seconds * 1000); }); };
在嵌套循环内的每个交换操作后将调用
sleep()
函数的排序函数async sort() { const elements = [...this.state.elements]; const length = elements.length; for (let i = 0; i < length; i++) { for (let j = i + 1; j < length; j++) { if (this.state.elements[i].value > this.state.elements[j].value) { const temp = elements[i]; elements[i] = elements[j]; elements[j] = temp; this.setState({ elements }); await this.sleep(1.5); } } } };