selfcreditgiving
V2EX  ›  问与答

js 这样筛选对象数据,怎么比较好

  •  
  •   selfcreditgiving · Jul 19, 2019 · 2548 views
    This topic created in 2515 days ago, the information mentioned may be changed or developed.

    请问大佬有什么比较简洁一点的写法吗?

    const cmds = [
        {name:"a", cmd:"111"},
        {name:"b", cmd:"222"},
        {name:"c", cmd:"333"},
        {name:"d", cmd:"444"},
    ];
    
    const needExecs = [
        {startCmd:"a", endCmd:"b"},
        {startCmd:"d", endCmd:"d"},
    ]
    
    // 希望得到过滤后的结果
    [
        {name:"a", cmd:"111"},
        {name:"b", cmd:"222"},
        {name:"d", cmd:"444"},
    ]
    
    6 replies    2019-07-20 01:45:56 +08:00
    finalwave
        1
    finalwave  
       Jul 19, 2019
    如果 cmds 和 needExecs 有序,就
    https://gist.github.com/Velocita/695f0631d094457230f8282a208318e2
    如果无序就两层循环暴力遍历看要不要 push 进 result
    finalwave
        2
    finalwave  
       Jul 19, 2019
    不翻墙载入不了链接。。。
    重发一下代码
    while (i<needExecs.length && j<cmds.length){
    if (needExecs[i] include cmds[j].name){
    result.push(cmds[j]);
    }else if (cmds[j].name left needExecs[i]){
    j++;
    }else{
    i++;
    }
    }
    selfcreditgiving
        3
    selfcreditgiving  
    OP
       Jul 19, 2019
    谢谢大佬回复 :)
    这两个数组的 name 属性不是有序的, 可以为任意字符串的。

    写了个暴力循环版的,先取到 startCmd 和 endCmd 在 cmds 数组里对应的 index,然后在分别过滤。
    ```
    const filteredCmds = cmds.filter((item, index) => {
    let hit = false;
    for (let i = 0; i < needExecs.length; i++) {
    const startIndex = cmds.findIndex(cmd => cmd.name === needExecs[i].startCmd);
    const endIndex = cmds.findIndex(cmd => cmd.name === needExecs[i].endCmd);
    if (index >= startIndex && index <= endIndex) {
    hit = true;
    break;
    }
    }
    return hit;
    });
    ```
    johnnyNg
        4
    johnnyNg  
       Jul 19, 2019
    cmds.filter(({name}) => needExecs.find(({startCmd, endCmd}) => startCmd === name || endCmd === name))
    selfcreditgiving
        5
    selfcreditgiving  
    OP
       Jul 19, 2019
    @johnnyNg 666, 可以用对象解构。只是意思有点点出入,startCmd、endCmd 的意思是 cmds 数组中,name 值以哪个开始,以哪个结束,

    例如:如果 startCmd: "a", endCmd: "c",那么过滤出来的结果应该是
    [
    {name: "a", cmd: "111"},
    {name: "b", cmd: "222"},
    {name: "c", cmd: "333"},
    ]
    autoxbc
        6
    autoxbc  
       Jul 20, 2019
    如果 name 就是单个字母,那么可以考虑拼接正则

    const mapFn = ({ startCmd , endCmd }) => startCmd + '-' + endCmd ;
    const regExp = new RegExp(`^[${ needExecs.map(mapFn).join('') }]$`);
    console.log( cmds.filter( ({ name }) => regExp.test(name) ) );
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2825 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 09:59 · PVG 17:59 · LAX 02:59 · JFK 05:59
    ♥ Do have faith in what you're doing.