Filter and delete filtered elements in an array

前端 未结 6 1466
遥遥无期
遥遥无期 2020-12-09 16:32

I want to remove specific elements in the original array (which is var a). I filter() that array and splice() returned new array. but

相关标签:
6条回答
  • 2020-12-09 17:15

    The Array.prototype.filter() method is used to collect an element set not only one item. If you would like to get one item by evaluating a condition then you have three other options. Array.prototype.indexOf(), Array.prototype.findIndex() and Array.prototype.find() Accordingly only if you want to make an operation on more than one item you should think using the filter function. None of the answers are complete in terms of the job needed to be done. They use the filter function to isolate a set (happens to be only one item in this example) but they don't show how to get rid of the whole set. Well ok let's clarify.

    If you want to do find and delete only one item of your array it shall be done like this

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}];
    a.splice(a.findIndex(e => e.name === "tc_001"),1);
    console.log(a);

    However since you mention "specific elements" in plural, then you will need to collect a set of selected items and do the above job one by one on each element in the set. So the proper approach would be.

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}],
        b = a.filter(e => e.name === "tc_001");
    b.forEach(f => a.splice(a.findIndex(e => e.name === f.name),1));
    console.log(a);

    Regardless of how many elements there are in your selected list this will do your job. Yet i believe although this looks logical it does tons of redundant job. First filters and then per filtered element does index search this and that. Although i know that findIndex is crazy fast still I would expect this one turn out to be noticeably slow especially with big arrays. Let's find an o(n) solution. Here you go

        var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}];
        a = a.reduce((p,c) => (c.name !== "tc_001" && p.push(c),p),[]);
    console.log(a);

    So this must be it.

    0 讨论(0)
  • 2020-12-09 17:18

    So if I understood, you want to remove the elements that matches the filter from the original array (a) but keep them in the new array (b) See if this solution is what you need:

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}]
    
    var b = a.filter(function (e) {
          return e.name === 'tc_002'
    });
    
    b.forEach(function(element) {
       console.log(element)
       var index = a.indexOf(element)
       console.log(index)
       a.splice(index, 1)
    })
    

    Result: a = [{"name":"tc_001"},{"name":"tc_003"}] b = [{"name":"tc_002"}]

    0 讨论(0)
  • 2020-12-09 17:23

    another way is filtering in two list like below:

    const originalList = [{condition:true}, {condition: false}, {condition: true}];
    
    // wished lists
    const listWithTrue = originalList.filter(x=>x.condition);
    const listWithFalse = originalList.filter(x=>!x.condition); // inverse condition
    
    0 讨论(0)
  • 2020-12-09 17:24

    You can either make changes to the original array:

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}]
    a = a.filter(function (e) {
        return e.name === 'tc_001';
    });
    a.splice(0,1);
    

    Or in your own code just apply to a everything you've done to b

    a = b
    

    [edit]

    Perhaps if I expand on what each action does, it will be more clear.

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}]
    // You now have array a with 3 elements.
    
    b = a.filter(function (e) {
        return e.name === 'tc_001';
    });
    // a is still 3 elements, b has one element (tc_001)
    
    b.splice(0,1);
    // You remove the first element from b, so b is now empty.
    

    If you want to remove the elements tc_002 and tc_003 from a but keep them in b, this is what you can do:

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}]
    b = a.filter(function (e) {
        return e.name != 'tc_001';
    });
    a = a.filter(function(item) { return b.indexOf(item) == -1; });
    console.log(a); // tc_001
    console.log(b); // tc_002, tc_003
    
    0 讨论(0)
  • 2020-12-09 17:32

    I know I'm a little bit late to the party, but how about a little bit different approach?

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_002'}, {name:'tc_002'}, {name:'tc_003'}];
    
    while ( a.findIndex(e => e.name === 'tc_002' ) >= 0 )
     a.splice( a.findIndex(f => f.name === 'tc_002'),1);
     
    console.log(a);

    I know it has some drawbacks, but i hope, it will help some of you in some cases :)

    cheers!

    0 讨论(0)
  • 2020-12-09 17:33

    You can assign filter array to a itself and then apply splice over it.

    Example below:

    var a = [{name:'tc_001'}, {name:'tc_002'}, {name:'tc_003'}]
    a = a.filter(function (e) {
        return e.name === 'tc_001';
    });
    
    a.splice(0,1);
    
    0 讨论(0)
提交回复
热议问题