V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bw2
V2EX  ›  程序员

我们一起来做一道 JS 题目:在控制台打印 React 仓库的 Fork 列表

  •  
  •   bw2 ·
    bergwhite · 2017-07-11 13:34:36 +08:00 · 4524 次点击
    这是一个创建于 2674 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要求

    
    获取当前页面已 Fork 的成员列表,存储在数组。代码短,耗时少者更佳。返回数组长度应该是 1000。
    
    

    地址

    https://github.com/facebook/react/network/members

    示例代码

    
    // 时间和函数长度统计
    
    function timeAndLengthCount(callback){
      const timeStart = new Date().getTime()
      callback()
      const timeEnd = new Date().getTime()
      console.log('Time: ' + (timeEnd-timeStart) + 'ms')
      console.log('Len: '+ callback.toString().length)
    }
    
    // 执行输出 Fork 成员列表的函数
    // Time: 7ms
    // Len: 223
    
    timeAndLengthCount(()=>{
      const forkedMenber = document.querySelectorAll('.repo > a:nth-child(odd)');
      const forkedMenberList = [];
      [].forEach.call(forkedMenber, z => forkedMenberList.push(z.innerHTML));
      console.log(forkedMenberList);
    })
    
    

    接下来就是开始你的表演了

    http://img1.imgtn.bdimg.com/it/u=3007745223,2279606714&fm=26&gp=0.jpg

    47 条回复    2017-07-12 13:17:46 +08:00
    nino
        1
    nino  
       2017-07-11 13:56:08 +08:00   ❤️ 1
    [...document.querySelectorAll('#network .repo > a:first-of-type')].map(el => el.textContent)
    xiaojie668329
        2
    xiaojie668329  
       2017-07-11 13:59:37 +08:00 via iPhone   ❤️ 1
    把 querySelectorAll 换成 getElementsBy...会变快。
    zjsxwc
        3
    zjsxwc  
       2017-07-11 14:00:43 +08:00   ❤️ 1
    剩下的就是 css 选择器的花式写法了
    bw2
        4
    bw2  
    OP
       2017-07-11 14:03:51 +08:00
    @nino 厉害了,把我的代码压缩成了一行,就扶你
    bw2
        5
    bw2  
    OP
       2017-07-11 14:04:54 +08:00
    @xiaojie668329 确实,然后使用正则?
    bw2
        6
    bw2  
    OP
       2017-07-11 14:05:25 +08:00
    @zjsxwc 我觉得还有别的玩法
    bw2
        7
    bw2  
    OP
       2017-07-11 14:08:45 +08:00
    最新记录是 @nino
    Time: 2ms
    Len: 96
    Wangxf
        8
    Wangxf  
       2017-07-11 14:09:38 +08:00   ❤️ 1
    [...document.querySelectorAll('.repo')].slice(1).map((item)=>item.children[2].innerHTML)
    crs0910
        9
    crs0910  
       2017-07-11 14:14:11 +08:00   ❤️ 1
    document.querySelector('#network').textContent.replace(/\s/g, '').split('/react')
    bw2
        10
    bw2  
    OP
       2017-07-11 14:17:34 +08:00
    @Wangxf

    Time: 4ms
    Len: 92
    bw2
        11
    bw2  
    OP
       2017-07-11 14:18:56 +08:00
    @crs0910
    Time: 2ms
    Len: 85

    但是,返回数组是 1001,数组的第一个'facebook',不在需求范围内
    hueo
        12
    hueo  
       2017-07-11 14:20:38 +08:00   ❤️ 1
    要考虑性能的话正则是最快的。

    不过昨天的代码是这样的:

    Array.from(document.querySelectorAll('#network .repo > img + a'), e => e.href)
    crs0910
        13
    crs0910  
       2017-07-11 14:21:27 +08:00
    加个 shift 不就得了,我测是 1ms
    crs0910
        14
    crs0910  
       2017-07-11 14:28:10 +08:00
    @xiaojie668329 貌似 querySelector\querySelectorAll 都比 getElementById\getElementsByTag 要快,我是最新的 Chrome.
    https://jsperf.com/getelementsbytagname-a-0-vs-queryselector-a/4
    bw2
        15
    bw2  
    OP
       2017-07-11 14:32:33 +08:00
    @crs0910 加 shift 之后返回的是'facebook',你试试,需求是打印一个数组,长度 1000
    bw2
        16
    bw2  
    OP
       2017-07-11 14:33:33 +08:00
    @hueo 就是昨天看到你的,才突发奇想的
    Wangxf
        17
    Wangxf  
       2017-07-11 14:37:32 +08:00
    [...document.getElementById('network').getElementsByTagName('a')].filter((item,index)=>index%2===0).map((item)=>item.innerHTML).slice(1);
    crs0910
        18
    crs0910  
       2017-07-11 14:40:30 +08:00
    @bw2
    document.getElementById('network').textContent.replace(/\s/g, '').split('/react').slice(1)) document.getElementById('network').textContent.replace(/\s/g, '').split('/react').splice(1))
    Wangxf
        19
    Wangxf  
       2017-07-11 14:44:57 +08:00
    最新版 1.5s
    [...document.getElementById('network').querySelectorAll('a:nth-child(odd)')].slice(1).map((item)=>item.innerHTML)
    crs0910
        20
    crs0910  
       2017-07-11 15:01:22 +08:00   ❤️ 1
    去掉一个 replace 的版本

    document.querySelector('#network').textContent.split(/\s*\/\s*react\s*/g).splice(1)
    colorwin
        21
    colorwin  
       2017-07-11 15:19:51 +08:00
    你们的电脑的真好....我的古董机跑你们的代码要慢 5s 以上...
    iiji86
        22
    iiji86  
       2017-07-11 15:22:56 +08:00   ❤️ 1
    [...document.querySelectorAll('img+a')].map(_=>_.text)
    colorwin
        23
    colorwin  
       2017-07-11 15:23:44 +08:00
    同时也很不稳定啊, 同一段代码最慢有 24, 快的有 11
    ctsed
        24
    ctsed  
       2017-07-11 15:57:39 +08:00   ❤️ 1
    network.innerHTML.match(/@[^"]*/g).join().split('@').slice(2) 5ms 61

    [...network.querySelectorAll('img+a')].map(_=>_.text) 1ms 53
    bw2
        25
    bw2  
    OP
       2017-07-11 15:58:24 +08:00
    厉害了,最新记录是 @crs0910
    Time: 1ms
    Len: 87

    document.querySelector('#network').textContent.split(/\s*\/\s*react\s*/g).splice(1)
    bw2
        26
    bw2  
    OP
       2017-07-11 15:59:57 +08:00
    @Wangxf 我这边测试是 2ms,我的电脑还是要差一点
    bw2
        27
    bw2  
    OP
       2017-07-11 16:01:39 +08:00
    @colorwin 该升级配置了
    bw2
        28
    bw2  
    OP
       2017-07-11 16:04:34 +08:00
    @iiji86 我怎么就没有想出这么好的操作
    Time: 2ms
    Len: 58
    bw2
        29
    bw2  
    OP
       2017-07-11 16:06:51 +08:00
    @ctsed network.querySelectorAll ?
    jun0205
        30
    jun0205  
       2017-07-11 16:13:56 +08:00   ❤️ 1
    [...document.querySelectorAll('.network-tree ~ a:not(:last-child)')].map(el=>el.text)
    ctsed
        31
    ctsed  
       2017-07-11 16:18:29 +08:00
    network.innerText.split(/\s*\/\s*react\s*/g).splice(1)
    2ms 50
    ctsed
        32
    ctsed  
       2017-07-11 16:20:47 +08:00
    network.innerText.split(/ \/ react\s*/g).splice(1)

    48
    ctsed
        33
    ctsed  
       2017-07-11 16:23:01 +08:00   ❤️ 1
    其实控制台用$$也可以
    [...$$('img+a')].map(_=>_.text)
    cain
        34
    cain  
       2017-07-11 16:28:42 +08:00   ❤️ 2
    时间统计可以用 window.performance.now() 代替获取时间的方法
    bw2
        35
    bw2  
    OP
       2017-07-11 16:57:11 +08:00
    @ctsed 还有这种操作

    Time: 2ms
    Len: 35
    bw2
        36
    bw2  
    OP
       2017-07-11 16:58:48 +08:00
    @ctsed 请问为什么输入 network 可以直接访问到对应的节点,输入 start-of-content 却访问不到 id 为 start-of-content 的节点
    bw2
        37
    bw2  
    OP
       2017-07-11 17:00:20 +08:00
    @cain 这个方法很赞
    bw2
        38
    bw2  
    OP
       2017-07-11 17:03:13 +08:00
    @jun0205 花式选择器 get

    Time: 1.8699999991804361ms
    Len: 89
    simo
        39
    simo  
       2017-07-11 17:06:48 +08:00
    看完回复,再也不想干前端了
    ctsed
        40
    ctsed  
       2017-07-11 17:14:44 +08:00
    @bw2 - 被解析后当作减法执行了
    baconrad
        41
    baconrad  
       2017-07-11 17:17:12 +08:00   ❤️ 1
    @bw2 因為 start-of-content 會被理解為三個變數兩個運算符,
    但仍然能用 window['start-of-content'] 來取得節點
    bw2
        42
    bw2  
    OP
       2017-07-11 17:58:42 +08:00
    @ctsed 厉害了,竟然有这种操作
    bw2
        43
    bw2  
    OP
       2017-07-11 17:59:55 +08:00
    @baconrad 对象里的['']用过,没想到在最外层还能直接执行[''],真是涨见识了
    crs0910
        44
    crs0910  
       2017-07-11 18:01:05 +08:00
    innerText 需要判断 layout,会有额外的性能损耗
    tgxh
        45
    tgxh  
       2017-07-11 18:07:10 +08:00   ❤️ 1
    $$('.repo > a:not(:last-child)').map(el => el.textContent)
    colorwin
        46
    colorwin  
       2017-07-12 09:56:29 +08:00
    @bw2 老古董, 升不动了. 靠 Linux 强行续命. 习惯了 Ubuntu 之后, 现在有点犹豫要不要买 Mac 了. 感觉相比下 Mac 性价比好低...
    xqin
        47
    xqin  
       2017-07-12 13:17:46 +08:00   ❤️ 4
    @crs0910 你最后发的代码 ``` document.querySelector('#network').textContent.split(/\s*\/\s*react\s*/g).splice(1) ```
    长度是对了, 但得到的 用户名不正确. 因为后面有一些 repo 的名字是 react-1, react-tap-event-plugin ....

    而你的正则上面直接按 react 来分隔, 会导致 -1 , -tap-event-plugin 成为 后面用户名的一部分.
    另外还有一个 repo 的名字是 facebook-react

    所以正则需要再更新一下, 否则, 即便匹配出来了, 结果是 1000, 但得到的用户名是不正确的, 且数组的最后一个元素是空的, 也是错的.


    更新后的代码如下:
    network.innerText.split(/ \/ \S+\s+/g).slice(1, -1)



    @ctsed 您的回复也存在同样的问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5316 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 05:45 · PVG 13:45 · LAX 21:45 · JFK 00:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.