【问题标题】:How to simplify nested loops and conditions?如何简化嵌套循环和条件?
【发布时间】:2013-07-19 23:50:47
【问题描述】:

给定一个JS如下:

for (c in chars) {
    for (i in data) {
        if (data[i].item === chars[c]) {
            // do my stuff;
        }
        else { /* do something else */}
    }
}

还有这样的数据:

var chars = [ 'A', 'B', 'C', 'A', 'C' ];
var data = [
    {'item':'A', 'rank': '1'}, 
    {'item':'B', 'rank': '2'}, 
    {'item':'C', 'rank': '3'}
    // no duplicate
];

有没有比嵌套for 循环和内部条件更简单的语法来表达?

我尝试匹配两个数据集,更准确地说是使用chars 的键来迭代data 并查找值。

【问题讨论】:

  • 等等,你想iterate over an array with for in吗?
  • @acdcjunior 它有效。请记住,迭代变量设置为索引,而不是值(它不像 PHP foreach)。
  • @Barmar 什么有效?数组的for in?如果是这样,我并不是说它没有,我说不应该,因为它会搞砸你的代码。
  • ...或者像这样:jsfiddle.net/bysBH/7
  • @Hugolpz:是的,我认为您的嵌套循环非常简单。在这种特定情况下,键/值映射绝对是要走的路。也会更快。

标签: javascript jquery json


【解决方案1】:

你可以这样做:

for (i = 0; i < data.length; i++) {
    if (chars.indexOf(data[i].item) != -1) {
        // Do something
    } else {
        // Do something else
    }
}

但是,如果chars 很大,我将创建一个对象,其键是chars 的元素并使用if (chars_obj[data[i].item])。这比每次都搜索一个数组更有效率。

【讨论】:

  • 附注:旧版浏览器不支持Array.indexOf
  • 我不知道OP具体需要什么,但是如果chars数组中有多个相同的字母,这会有点不同。
  • @Barmar 这不是 OP 想要的。对于 OP 示例,执行了 15 个函数(我的东西或其他东西)。
【解决方案2】:

简化代码的另一种方法是将其封装并抽象为一个接受回调的实用程序,而不是在需要时重用它,如下所示:

// definition
function eachChar(onMatch, onMismatch) {
    for (c in chars) {
        for (i in data) {
            if (data[i].item === chars[c]) {
                typeof onMatch === 'function' && onMatch(); 
            } else {
                typeof onMismatch === 'function' && onMismatch(); 
            }
        }
    }
}

// usage examples
eachChar(function() {
    // do something when it's a match
});
eachChar(function() {
    // do something when it's a match
}, function() {
    // do something else when it's not
});

查看live demo on jsFiddle


作为旁注,您可能希望显式声明用作循环索引的变量,以免将它们暴露在外部范围(例如 global 范围):

// that:
for (c in chars) {
    for (i in data) {

// would become this:
for (var c in chars) {
    for (var i in data) {

【讨论】:

    【解决方案3】:

    由于您标记了您的问题 jquery,您可以使用 jquery 解决方案:

    $.each(chars, function (cndx, chr) {
        $.each(data, function (dndx, datum) {
            if (datum.item === chr) {
                // do my stuff;
            } else {
                /* do something else */
            }
        }
    });
    

    不再简洁,但至少你不必索引。

    【讨论】:

    • 其实并不简单,只是伪装。
    • 不完全正确——索引通常是微妙错误的载体。
    猜你喜欢
    • 2022-12-07
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多