Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在深度迭代的第一个真实结果时停止回调函数_Javascript_Reactjs - Fatal编程技术网

Javascript 如何在深度迭代的第一个真实结果时停止回调函数

Javascript 如何在深度迭代的第一个真实结果时停止回调函数,javascript,reactjs,Javascript,Reactjs,我正在为瑜伽课程开发一个应用程序 [编辑] 为了更好地举例说明我的问题,我对我的状态进行了编辑。在收到的所有答案中,结果将在this.state.existingElements中的第一个现有元素时停止。现在,我已经在对象的数组中添加了另一个实例(this.state.existingElements),以明确迭代应该设置state,只对每个现有元素执行一次。下面我自己的答案仍然得到了预期的结果,但我认为这不是最佳答案 [/EDITED] ………=> 以下是交易的背景: 每当讲师想要创建一个新类

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

[编辑]

为了更好地举例说明我的问题,我对我的
状态进行了编辑。在收到的所有答案中,结果将在
this.state.existingElements
中的第一个现有元素时停止。现在,我已经在
对象的
数组中添加了另一个
实例
this.state.existingElements
),以明确迭代应该
设置state
,只对每个现有元素执行一次。下面我自己的答案仍然得到了预期的结果,但我认为这不是最佳答案

[/EDITED]

………=>

以下是交易的背景:

每当讲师想要创建一个新类时,我设置了一个
函数
,该函数将获取新类的开始日期、小时和分钟,根据讲师设置的持续时间计算该类的结束时间,然后创建一个对象,该对象在其一个实例上具有一个数组,该数组将在该类的每一分钟内结束,从开始到结束,以毫秒为单位

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

我想比较每个类的运行时间,以确定新类是否与以前设置的任何现有类冲突

我带来了这段代码,但在逻辑的末尾遇到了问题

当我执行此语句时,
if(existingElement.elapse.includes(newFraction))
我希望它在第一个
true
返回时停止迭代,因此我不会将同一个现有冲突类再次推送到
this.state。冲突类

我尝试过其他格式。。。我尝试使用
some()
,尝试将
if(existingElement.elapse.includes(newFraction))
替换为另一个
.forEach()
更深的迭代,因此我会比较每个
数组的每个实例,将
if
语句移到更深的
forEach()

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

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

我希望我说得很清楚:我希望在
existingElement中第一次找到
newFraction
时停止此迭代。因此,我只对
existingElement执行一次
setState

我会把代码贴在下面,然后

从“React”导入React;
导入“/styles.css”;
导出默认类App扩展React.Component{
状态={
conflictingClasses:[],//在本例中,它应该在这里获得id 2和id 3
现有要素:[
{id:1,经过:[1,2,3,4]},
{id:2,过去:[5,6,7,8]},
{id:3,过去:[9,10,11,12]}
],
新元素:[
{id:3,过去:[8,9,10,11]},
{id:4,消逝:[13,14,15,99]}
]
};
newElementsValidatorHandler=()=>{
this.state.existingElements.forEach(existingElement=>{
返回this.state.newElements.forEach(newElement=>
newElement.elapse.some(newFraction=>{
if(existingElement.elapse.includes(newFraction)){
this.setState(({conflictingClasses,…restop})=>({
冲突类别:[
…冲突类.filter(
prevClasses=>prevClasses!==existingElement
),
现有元素
],
…休息室
}));
}
})
);
});
};
render(){
返回(
你好,代码沙盒
运行测试!
显示冲突元素:
{this.state.conflictingClasses.map(conflictingClass=>(

冲突id:{conflictingClass.id}

))} ); } }
没有内置的方法将
映射中分离出来,
一些
forEach
,因此我创建了一个自定义类

class BreakableLoopingArray {

  constructor(data) {
    this.data = data
  }

  forEach(callback) {

    // Create a flag to determine whether loop should proceed
    let shouldStop = false

    // A setter function to modify the flag
    const breakLoop = () => { shouldStop = true }

    for (let i = 0; i < this.data.length && !shouldStop; i++) {
      callback({
        item: this.data[i],
        index: i,
        self: this.data,
        breakLoop,
      })
    }
  }

}


下面是通过创建自定义异常来打破这些循环的另一种方法,但这会使代码复杂化,尤其是当您进行深度嵌套时。(只是额外的知识嗯,正如我所说,我可以过滤
oldState

(根据该问题的版本)

我在这里能做的更有效率吗?因为我真正想要的是跳出循环,在
this.state.existingElements中为每个冲突对象设置
state
一次

conflictingClasses: [
                ...conflictingClasses.filter(
                  prevClasses => prevClasses !== existingElement
                ),
                existingElement
              ],
整个交易:

 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
            }));
          }
        })
      );
    });
  };

我提出了一个解决方案,但是它重新组织了你的功能。我愿意听取其他人关于如何改进的任何建议

首先,我删除了对
map
的所有调用。map将迭代一个数组,但它也会返回一个新版本的数组

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

[已编辑]

第三,也是最后一点,您可以简单地将回调函数中的现有结果过滤到
setState
,并仅返回包含newElementsValueArray中的值的现有元素

这是你的电话号码

我希望在找到新分数时停止此迭代 第一次在existingElement.elapse中,所以我只执行一次设置状态 每个现有元素

确实,您不能预先中止.forEach和.map,因为returning只会从当前回调调用返回,而不会取消其余调用

我想指出的第一件事
conflictingClasses: [
                ...conflictingClasses.filter(
                  prevClasses => prevClasses !== existingElement
                ),
                existingElement
              ],
 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
            }));
          }
        })
      );
    });
  };
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
  }));
}
newElementsValidatorHandler = () => {
  this.state.existingElements.forEach(existingElement => {
    if (existingElementIncludesNewFraction(existingElement)) {
      this.setState(({ conflictingClasses }) => ({
        conflictingClasses: [...conflictingClasses, existingElement]
      }))
    }
  })
}


existingElementIncludesNewFraction = (existingElement) => {
  for (const newElement of this.state.newElements) {
    for (const newFraction of newElement.elapse) {
      if (existingElement.elapse.includes(newFraction)) {
        return true
      }
    }
  }
}
newElementsValidatorHandler = () => {
  const newConflictingClasses = this.state.existingElements.filter(existingElement => existingElementIncludesNewFraction(existingElement))
  this.setState(({ conflictingClasses }) => ({
    conflictingClasses: [...conflictingClasses, newConflictingClasses]
  }))
}
for (let i = 0; !conflictingClasses.includes(existingElement); i++) {
         conflictingClasses.push(existingElement);
            }    

aForSolutionHandler = () => {
    const existinElements = [...this.state.existingElements];
    const newElements = [...this.state.newElements];
    let conflictingClasses = [];
    //here I loop in the existing elements array
    for (let existingElement of existinElements) {
      //here I loop in the new elements array
      for (let newElement of newElements) {
        //here I iterate each value of elapse of each new element
        newElement.elapse.some(newFraction => {
          //if any fraction is found in any value of elapse of existing elements return true
          if (existingElement.elapse.includes(newFraction)) {
            //here I limit the number of iterations to expose the conflicting elements only once per element, to avoid the issue, object of our discussion
            for (
              let i = 0;
              !conflictingClasses.includes(existingElement);
              i++
            ) {
              conflictingClasses.push(existingElement);
            }
          }
        });
      }
    }
   //now I use the dummy array to send it to my state
    this.setState({ conflictingClasses });
  };