当前位置 主页 > 服务器问题 > Linux/apache问题 >

    详解如何在JS代码中消灭for循环

    栏目:Linux/apache问题 时间:2019-12-11 16:52

    Edit: 在我入职第三家公司的第一天,看到代码库里面一堆的 for 循环,内心有些崩溃,于是做了一次技术分享,展示怎样在代码中避免 for 循环。这篇文章是那次分享的总结。本文并不完美,其中递归的部分其实不应该在目前的生产环境中使用。但是我依然坚持认为 JS 引擎应该支持尾调优化,写尾递归和写循环性能没差别。

    一,用好 filter,map,和其它 ES6 新增的高阶遍历函数

    问题一:

    将数组中的 falsy 值去除

    const arrContainsEmptyVal = [3, 4, 5, 2, 3, undefined, null, 0, ""];

    答案:

    const compact = arr => arr.filter(Boolean);
    

    问题二:

    将数组中的 VIP 用户余额加 10

    const users = [
     { username: "Kelly", isVIP: true, balance: 20 },
     { username: "Tom", isVIP: false, balance: 19 },
     { username: "Stephanie", isVIP: true, balance: 30 }
    ];
    

    答案:

    users.map(
     user => (user.isVIP ? { ...user, balance: user.balance + 10 } : user)
    );
    

    补充:经网友提醒,这个答案存在浅拷贝的问题。操作引用型数据确实是一个麻烦的问题。下面提供两个方案:

    用 Ramda:

    import R from "ramda";
    
    const add10IfVIP = R.ifElse(
      R.propEq("isVIP", true),
      R.evolve({ balance: R.add(10) }),
      R.identity
    );
    
    const updateUsers = R.map(add10IfVIP);
    updateUsers(users);
    
    

    用 Immer

    如果你习惯写 mutable 的代码,可以试下 Immer,用 mutable 的风格写 immutable 的代码。

    import produce from "immer";
    
    const updatedUsers = produce(users, nextState => {
      nextState.forEach(user => {
      if (user.isVIP) {
        user.balance += 10;
        }
      });
    });
    
    

    问题三:

    判断字符串中是否含有元音字母

    const randomStr = "hdjrwqpi";
    

    答案:

    const isVowel = char => ["a", "e", "o", "i", "u"].includes(char);
    const containsVowel = str => [...str].some(isVowel);
    
    containsVowel(randomStr);
    
    

    问题四:

    判断用户是否全部是成年人

    const users = [
     { name: "Jim", age: 23 },
     { name: "Lily", age: 17 },
     { name: "Will", age: 25 }
    ];
    

    答案:

    users.every(user => user.age >= 18);
    

    问题五:

    找出上面用户中的第一个未成年人

    答案:

    const findTeen = users => users.find(user => user.age < 18);
    
    findTeen(users);
    
    

    问题六:

    将数组中重复项清除

    const dupArr = [1, 2, 3, 3, 3, 3, 6, 7];
    

    答案:

    const uniq = arr => [...new Set(arr)];
    
    uniq(dupArr);
    
    

    问题七:

    生成由随机整数组成的数组,数组长度和元素大小可自定义

    答案:

    const genNumArr = (length, limit) =>
     Array.from({ length }, _ => Math.floor(Math.random() * limit));
    
    genNumArr(10, 100);