JS怎样精简这样的循环

JavaScript
如下代码,循环里除了判断的条件不一样,其它都是一样的。判断的条件里有可能会包含i,也有可能不含i。有没有办法精简它们??

// obj 这是一个json
loop1(){
    for(let i=0;i<obj.length;i++){
        if(i%2!==0){
            doSomethingA()
        } else {
            doSomethingB()
        }
    }
}
loop2(){
    for(let i=0;i<obj.length;i++){
        if(i%2!==0 && i!==0){
            doSomethingA()
        } else {
            doSomethingB()
        }
    }
}
loop3()。。。
loop4()。。。
阅读 2.6k
4 个回答
// obj = xxxx

function loop (predicate) {
    for (let i = 0; i < obj.length; i++) {
        if (predicate(i)) {
            doSomethingA()
        } else {
            doSomethingB()
        }
    }
}

loop(i => i % 2 !== 0)
loop(i => i % 2 !== 0 && i !== 0)

// 举个例子
let isKeyExist = (obj, key) => !!obj[key]

let predicateFactory = (condition, i) => {
    // 意会
    if (condition) {
        return i % 2 === 0
    } else {
        return i % 2 === 0 && i !== 0
    }
}

loop() {
    for (let i = 0; i < obj.length; i++) {
        if (predicateFactory(isKeyExist(obj, 'foo'), i)) {
            doSomethingA()
        } else {
            doSomethingB()
        }
    }
}

至于那个 condition 是什么,就看你区分这些 loop 的依据是什么,想办法抽象一下看看。

这样可以把 什么情况使用什么判断方式 抽象出来,而不需要针对各种情况单独写一次 loop(...)
condition 想做成啥样都是看你想怎么抽象 情况判断方式 来搞。

当然如果不需要这么高层次抽象,那就可以多写几个 loop 来看情况调用,本质上跟上面抽象 condition 是一样的,只是代码调用上的区别。


比如来个稍微复杂点的:


const CONDITIONS = {
    OBJ_HAS_SOME_KEY: i => i % 2 === 0,
    OBJ_MISS_SOME_KEY: i => i % 2 === 0 && i !== 0
}

// 举个例子
let conditionMatch = obj => {
    let predicate = undefined
    
    if (obj[someKey]) {
        predicate = CONDITIONS.OBJ_HAS_SOME_KEY
    } else {
        predicate = CONDITIONS.OBJ_MISS_SOME_KEY
    }
    
    if (predicate === undefined) {
        throw new Error('无法找到任何能匹配的处理函数')
    }
    
    return predicate
}

loop() {
    for (let i = 0; i < obj.length; i++) {
        if (conditionMatch(obj)(i)) {
            doSomethingA()
        } else {
            doSomethingB()
        }
    }
}

如果还要能在 predicate 里使用 obj 啦、使用更多参数啦,那就不能让 predicate 是箭头函数了,使用 function 然后 return function() {return predicate.apply(obj, arguments)}

function loop (obj, fun) {
  for (let i = 0; i < obj.length; i++) {
    if (fun(i, obj)) {
      doSomethingA()
    } else {
      doSomethingB()
    }
  }
}

loop1 等价于 loop(obj, function(i) {return i % 2 !== 0})
loop2 等价于 loop(obj, function(i) {return i % 2 !== 0 && i !== 0})

let loop = (fun) => {
obj.forEach((v, k) => {

if (fun) {
} else {
}

})
}
loop(fun)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题