如何过滤这个数组

let list = [
        {name: 'tom', age: 10},
        {name: 'lee', age: 11},
        {name: 'rose', age: 12},
        {name: 'jane', age: 13}
    ]
let info = [
    {name: 'lee'},
    {name: 'rose'}
]

从list里过滤掉info里没有的,
除了用组成新数组的,有没有直接过滤不符合条件,改变原数组的办法或者其他,求集思广益,大神们

除了这种办法
let newList=[]
for(let i=0;i<list.length;i++){
    for(let j=0;j<info.length;j++){
        if (list[i].name===info[j].name){
            newList.push(list[i])
        }
    }
}
阅读 5.8k
14 个回答
let list = [
  { name: 'tom', age: 10 },
  { name: 'lee', age: 11 },
  { name: 'rose', age: 12 },
  { name: 'jane', age: 13 }
]
let info = [
  { name: 'lee' },
  { name: 'rose' }
]

let new_info = JSON.stringify(info);
const new_list = list.filter(function (val, ind) {
  // 假设不存在于list中
  if (new_info.indexOf(val.name)<0) {
    return true;
  }
})

console.log(new_list);

let new_info = JSON.stringify(info);修改为:
JSON.stringify(info).split('name').join(); 更健壮一些 ;

let names = info.map(val => val.name);
let newList = list.filter(val => names.indexOf(val.name) > -1);

如果 info 的数据类型可以改的话,改成一个 Map 就可以了,然后 key 值指向可以表示某个对象的属性,比如你这里可能就是 name。

之后过滤逻辑就是,遍历 list,然后根据唯一标识属性是否在 Map 中存在过滤它,复杂度 O(n)

const newList = list.filter(val => info.some(item => item.name === val.name))
let list = [
    { name: 'tom', age: 10 },
    { name: 'lee', age: 11 },
    { name: 'rose', age: 12 },
    { name: 'jane', age: 13 }
]
let info = [
    { name: 'lee' },
    { name: 'rose' }
]
let arr = [];
let crr = [];

function Fn(list, callback, arr) {

    list.filter(function(i, index) {
        if (callback(i)) {
            arr.push(i);
            //return true;
        } else {
            return false;
        }
    })

    return arr;
}

let Brr = Fn(list, function(data) {
    let Me = false
    for (let i = 0; i < info.length; i++) {
        if (info[i].name === data.name) {
            Me = true;
            break;
        } else {
            Me = false;
        }
    }
    if (Me) {
        console.log(1);
        return true;
    } else {
        console.log(2);
        return false;
    }
}, arr)


console.log(Brr);

const filterList = (list, info) => {
  return list.filter(item => {
    return [...new Set(info.map(i=>i.name))].includes(item.name)
  })
}
let info1 = [];
info.map(e=>info1.push(e.name))
let arr = list.filter(e=>info1.includes(e.name))     
console.log(arr) 

clipboard.png

let list = [
    { name: 'tom', age: 10 },
    { name: 'lee', age: 11 },
    { name: 'rose', age: 12 },
    { name: 'jane', age: 13 }
]
let info = [
    { name: 'lee' },
    { name: 'rose' }
]
let names = info.map(ele => ele.name)
let res = list.filter(ele => {
    return names.includes(ele.name)
})

上面的回答中先声明空数组以及用filter函数过滤数组的都算是创建新数组的方法,直接修改原数组可以这么写:

let list = [
    {name: 'tom', age: 10},
    {name: 'lee', age: 11},
    {name: 'rose', age: 12},
    {name: 'jane', age: 13}
];
let info = [
    {name: 'lee'},
    {name: 'rose'}
];
let findIndex = () => list.findIndex(n => info.some(e => e.name === n.name));
let index = findIndex();
while (index > -1) {
    list.splice(index, 1);
    index = findIndex();
}
console.log(list);
Array.prototype.groupBy = function(key){
this.key = key;
return this.reduce((result,item)=>{
    let groupby = item[this.key];
    let group = result[groupby];
    if(!group){
        group=new Array();
        result[groupby]=group;
    }
    group.push(item);
    return result;
},new Object())
};
let res= list.groupBy('name');
list = info.reduce((result,x)=>result.concat(res[x.name]),[]);

结果

0: Object { name: "lee", age: 11 }
1: Object { name: "rose", age: 12 }

let result = list.filter(item => info.some(vitem => item.name === vitem.name))

其实你已经做出来了不是吗?
只需要简单优化下就行了

方案一: 直接修改目标数组

// 1. 首先把(线性表)列表转成(散列)表结构, 用关键数据作为specialMap的键; 替换内层循环
// 这里info列表仅仅用来做过滤, 并不关心它的顺序.
// 其次, 散列结构访问速度更快
let specialMap= {};
for (let i in info)
    specialMap[info[i].name] = true;

for(let i=0;i<list.length;i++){
    // 2. 判断该项是否需要删除
    let item = list[i];
    if (!specialMap[item.name])
        // 3. 删除该项
        list.splice(i, 1);
}

方案二: 用中间量替换目标数组

// --------------------------------
// 或者用中间量来转换
let specialMap= {};
for (let i in info)
    specialMap[info[i].name] = true;
let results = list.filter(function(item){
    return specialMap[item.name];
});
list.length = 0;
Array.prototype.push.apply(list, results);

Array API参考, 希望能帮助你.

  1. 如何找出不符合条件的项——楼上的回答很多,我就不重复了
  2. 如何从原数组中剔除这些项——依次Array.prototype.splice(index, 1)
    // 把info数组改装一下,这样方便比较 先把对象 key 值遍历出来
    let info = [
        {name:'lee'},                     
        {name:'rose'}
    ].map(function(item){
        return item.name;
    });
    
    // 如果只想改变原来数组可以使用splice
    list.forEach(function(item, index, arr){
        if(!info.includes(item.name)){
            arr.splice(index,1)
        }
    });
    
    // 想返回新数组的话可以使用  filter
    let result = list.filter(function(item, index, arr){
        return info.includes(item.name)
    });
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题