首页 > 解决方案 > 如何在深度迭代的第一个真实结果处停止回调函数

问题描述

我正在为瑜伽课开发一个应用程序。

[编辑]

state为了更好地举例说明我的问题,我编辑了我的。在收到的所有答案上,结果将停止在 中的第一个现有元素上this.state.existingElements。现在我instancearrayof objects(this.state.existingElements ) 中添加了另一个,以明确setState每个现有元素的迭代应该只进行一次。下面我自己的答案仍然得到了预期的结果,但我认为这不是最佳的。

[/编辑]

......=>

只是为了在此处将交易背景化:

每当讲师想要创建一个新课程时,我设置了一个function将获取新课程的开始日期、小时和分钟,根据讲师设置的持续时间计算课程的结束时间,然后创建一个对象在它的一个实例中,有一个数组,该数组从开始到结束的每一分钟都经过,以毫秒为单位。

然后这个讨论的对象进入场景:

我想比较每个班级的时间,以确定新班级是否会与之前设置的任何现有班级发生冲突。

我附带了这段代码,但是在逻辑结束时遇到了麻烦。

当我执行此语句时,if (existingElement.elapse.includes(newFraction))我希望它在第一次true返回时停止迭代,因此我不再"push"使用相同的现有冲突类this.state. conflictingClasses

我尝试过其他格式...我尝试过使用some(),尝试替换if (existingElement.elapse.includes(newFraction))另一个.forEach()更深的迭代,所以我会比较 each 的每个实例array,将if语句更深地移动到更深的forEach().

我终于尝试while(!this.sate.conflictingClasses.includes(existingElement))在运行前使用 a setState,最后一次尝试冻结了应用程序哈哈。

我知道我可以将this.state.conflictingClasses其作为callbackof进行操作this.setState,以避免重复问题,但这仍然会使逻辑迭代变得更加必要。

我希望我说清楚了:我希望这个迭代newFraction在第一次被发现时停止,existingElement.elapse所以我setState每次只做一次existingElement

我将在下面和这里发布代码

import React from "react";
import "./styles.css";

export default class App extends React.Component {
  state = {
    conflictingClasses: [],//in this case it should get id 2 & id 3 in here
    existingElements: [
      { id: 1, elapse: [1, 2, 3, 4] },
      { id: 2, elapse: [5, 6, 7, 8] },
      { id: 3, elapse: [9, 10, 11, 12] }
    ],
    newElements: [
      { id: 3, elapse: [8, 9, 10, 11] },
      { id: 4, elapse: [13, 14, 15, 99] }
    ]
  };

  newElementsValidatorHandler = () => {
    this.state.existingElements.forEach(existingElement => {
      return this.state.newElements.forEach(newElement =>
        newElement.elapse.some(newFraction => {
          if (existingElement.elapse.includes(newFraction)) {
            this.setState(({ conflictingClasses, ...restTop }) => ({
              conflictingClasses: [
                ...conflictingClasses.filter(
                  prevClasses => prevClasses !== existingElement
                ),
                existingElement
              ],
              ...restTop
            }));
          }
        })
      );
    });
  };

  render() {
    return (
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <button onClick={this.newElementsValidatorHandler}>Run Tests!</button>
        <h2>Display Conflicting elements: </h2>
        {this.state.conflictingClasses.map(conflictingClass => (
          <p key={conflictingClass.id}>Conflicting Id: {conflictingClass.id}</p>
        ))}
      </div>
    );
  }
}

标签: javascriptreactjs

解决方案


我想出了一个解决方案,但它对您的功能进行了相当大的重组。我愿意接受其他人关于如何改进这一点的任何建议。

首先,我删除了所有对map. Map 将遍历一个数组,但它也会返回一个新版本的数组。

其次,我将所有新元素展平为一个数组。这样,您可以一次将现有元素中的时间与整个新元素进行比较。

[编辑]

第三,也是最后,您可以简单地filter将回调函数中的现有结果setState返回并仅返回包含来自 newElementsValueArray 的值的现有元素。

这是代码框

newElementsValidatorHandler = () => {
    // reduce the newElements array into an array of just the elapse values
    const newElements = this.state.newElements.reduce((arr, {elapse}) => {
      return [...arr, ...elapse];
    }, []);

    // add filtered existing elements to setState callback
    this.setState(({ conflictingClasses, ...restTop }) => ({
      conflictingClasses: [
      ...conflictingClasses,
      ...this.state.existingElements.filter(({elapse}) =>
        elapse.some(el => newElements.includes(el))
      )
    ],
    ...restTop
  }));
}

推荐阅读