2017-04-13 55 views
3

我想迭代使用forEach,并且当正确的元素被找到时,返回值。我的印象是forEach内的一个简单的return就足够了,但得知调用语句的结果是undefined如何从forEach退出拥抱方法?

因此,我不得不声明一个输出变量的作用域为整个方法,并勾选了所有元素,尽管已经找到了正确的那个。 (元素是唯一的。)

getMenuIndex(url) { 
    let output = -1; 

    this.menus.forEach(app => { 
    app.subs.forEach(sub => { 
     console.log(sub.link + " vs " + url); 
     if (sub.link === url) 
     // return sub.id; 
     output = sub.id; 
    }); 
    }); 

    return output; 
} 

这是代码味道很长的路。有没有更好的方法来选择匹配URL条件的元素的ID?

+1

[没有forEach的内置中断](http://stackoverflow.com/questions/2641347/how-to-short-circuit-array-foreach-like-calling-break) – Hodrobond

+0

而不是'forEach '你可以使用'find'。通过'Array.find'你可以通过返回'true'来停止迭代。 – Titus

+0

@Titus真实但不适用于我的情况。这个东西,如示例中所示是一个嵌套的生物。在实际的程序中,嵌套具有更深的层次。否则,好的建议,队友。 –

回答

5

幸运的是,我们在打字稿及ES6 for..of这样的场景:

getMenuIndex(url) { 
    for (const app of this.menus) { 
    for (const sub of app.subs) { 
     console.log(sub.link + " vs " + url); 
     if (sub.link === url) 
     return sub.id; 
    } 
    } 

    return -1; 
} 

它是在forEach的局限性是显而易见的情况下非常有用,比如await/yieldreturn/break

正如其他答案所说,有数组方法可能更适合这种情况。虽然对于TypeScript ES5目标for..of转换为常规for,因此是本身最快的解决方案。

+0

我更喜欢拉姆达风格的表情,因为它们让我看起来更性感。不过,我明白你的观点,你可能是对的,所以我同意它。 –

+0

我可能也是。有了函数式的方法,它可能会像'const {id = -1} = this.menus.reduce(...)。find(...)|| {};返回id',但它不会有效,即使开发人员进入FP也很难阅读。 – estus

1

您可以使用Array#some并退出true

function getMenuIndex(url) { 
    let output = -1; 
    this.menus.some(app => app.subs.some(sub => { 
     if (sub.link === url) { 
      output = sub.id; 
      return true; 
     } 
    })); 
    return output; 
} 
+0

然而,您正在以某种方式使用'some' **,而不是与您自己引用的描述在语义上兼容。有些人,我同情他们,认为这相当于折磨可爱的小猫咪。 – 2017-04-13 18:30:55

+0

@torazaburo,你的意思是错误的引用,或者使用一些不使用检查结果? –