NodeJS 使用javascript find方法添加动态过滤器

k3fezbri  于 2023-01-20  发布在  Node.js
关注(0)|答案(1)|浏览(171)
Input :

    First Array
    const input1 = [
    {
    'name':"name1",
    'email':"emai2@email.com",
    'age':10
    },
    {
    'name':"name2",
    'email':"emai2@email.com",
    'age':20
    }
    
    ];
    Second Array
    const input2 =[
    {
    'fullname':"name1",
    'emailaddress':"emai2@email.com",
    'age':10
    },
    {
    'name':"name2",
    'email':"emai2@email.com",
    'age':20
    }
    
    ];
    const filter1 = ['name', 'email'];
    const filter2 = ['fullname','emailaddress'];
    const matchArray = [];
    const newArray = [];
    let filterInput ='';
    
    function filterRecord(input1, input2, filter1, filter2) {
    filter1.forEach((data, index) =>{
    if((filter1.lenght)-1 ==index)){
    filterInput +='obj['+data+']==='+input2[index]+']';
    }
    
    else {
    if((filter1.lenght)-1 ==index)){
    filterInput +='obj['+data+']==='+input2[index]+'] && ';
    }
    });
     input1.forEach((data, index) =>{
    const isExist = input2.find((obj) =>filterInput);
     if(isExist){
       matchArray.push(isexist);
}
else {
newArray.push(isexist);
}
});
return {matchArray, newArray}
}

过滤器记录(输入1、输入2、过滤器1、过滤器2)
所以我需要在两个数组中检查的键是动态的。上面的代码没有按预期工作。匹配记录应该推入matchArray,不匹配记录应该推入newArray。但是目前我在find中传递的过滤器输入没有工作

mwkjh3gx

mwkjh3gx1#

您提供的代码未按预期工作,因为在filterRecord函数中,未正确构造filterInput变量。您使用filter1数组构造filterInput变量,但尝试访问input2数组中的值。此外,您使用单个等号进行比较,这对于比较两个变量是不正确的。
以下是更新函数以正确过滤记录的一种方法:

function filterRecord(input1, input2, filter1, filter2) {
    let filterInput = '';
    filter1.forEach((data, index) => {
        if (index === (filter1.length - 1)) {
            filterInput += `obj.${data} === data.${filter2[index]}`;
        } else {
            filterInput += `obj.${data} === data.${filter2[index]} && `;
        }
    });

    input1.forEach(data => {
        const isExist = input2.find(obj => eval(filterInput));
        if (isExist) {
            matchArray.push(isExist);
        } else {
            newArray.push(data);
        }
    });
    return { matchArray, newArray };
}

在此更新版本中,filterInput变量是通过迭代filter1数组并使用filter2数组中的相应值进行比较来构造的。它使用三个等号进行比较,而不是使用单个等号,这是比较两个变量的正确方法。此外,它还使用eval()方法将filterInput变量作为find()方法内的条件进行求值,这样它将按预期工作。
请记住,通常不建议使用eval(),因为它可能存在安全风险,而且速度也可能很慢。您应该使用更安全、更快速的方法来评估条件,但由于这是一个小示例,并且过滤器输入是硬编码的,因此可以接受。
UPD:
过滤记录的一个更好的方法是组合使用filter和Array原型的一些方法。下面是如何使用这些方法来过滤记录的示例:

function filterRecord(input1, input2, filter1, filter2) {
    matchArray = input1.filter((data) => input2.some((obj) => filter1.every(key => data[key] === obj[filter2[filter1.indexOf(key)]])));
    newArray = input1.filter((data) => !input2.some((obj) => filter1.every(key => data[key] === obj[filter2[filter1.indexOf(key)]])));
    return {matchArray, newArray};
}

在此示例中,filter方法用于根据some方法提供的条件筛选input1中的记录。如果input2中至少有一个元素与条件匹配,则some方法返回true。条件由every方法定义。其检查是否filter1中的所有元素与input2中的filter2中的对应元素匹配。indexOf方法用于获取filter1中键的索引,此索引用于获取filter2中对应的键。
请注意,这种方法将比以前的方法运行得更快,因为它没有使用eval,也不需要为每条记录迭代数组,它将在一次迭代中过滤记录。
更新2:
你是对的,迭代数组两次会花费更多的时间,特别是对于大量的记录。一种优化方法是使用散列表存储input2的记录,然后使用散列表检查input1中的记录是否存在于input2中。这将减少迭代次数并提高性能。
下面是一个如何使用散列表过滤记录的示例:

function filterRecord(input1, input2, filter1, filter2) {
    const hashmap = {};
    input2.forEach(item => {
        let key = '';
        filter1.forEach(f => {
            key += item[filter2[filter1.indexOf(f)]] + '_';
        });
        hashmap[key] = item;
    });
    matchArray = input1.filter(item => {
        let key = '';
        filter1.forEach(f => {
            key += item[f] + '_';
        });
        return hashmap[key];
    });
    newArray = input1.filter(item => !matchArray.includes(item));
    return {matchArray, newArray};
}

在此示例中,input2数组迭代一次以创建散列表,其中的键是使用filter1键的值构造的。然后,input1数组迭代一次,对于input1中的每个元素,都使用filter1键的值构造一个键。如果散列表中存在键,则input1中的元素被视为匹配。并添加到matchArray中,input1中不在matchArray中的元素添加到newArray中。
因为我们只迭代input2数组一次,然后我们使用hashmap来检查input1数组中是否存在元素,这种方法比两次迭代要快得多。

相关问题