简体   繁体   中英

Filter an array of objects based on filter criteria in another array of objects: JavaScript

I wish to filter myArray based on criteria mentioned in myFilter . The keys of myFilter are defined and could be accessed using myFilter.field , myFilter.value where as key:value of myArray are unknown. We might have to iterate over each object in myArray to first match the myArray [key] with myFilter.field and then to that myArray [key] to myFilter.value.

That should be an AND logic

 myArray = [{ make: "Honda", model: "CRV", year: "2017" }, { make: "Toyota", model: "Camry", year: "2020" }, { make: "Chevy", model: "Camaro", year: "2020" } ] myFilter = [{ field: "make", value: "Chevy", type: "string" }, { field: "year", value: "2020", type: "date" } ]; // Expected OutPut: myArray = [{ make: "Chevy", model: "Camaro", year: "2020" }] var tempArray = []; const keysToMatch = myFilter.length; let matchedItems = []; myArray.forEach((data) => { matchedItems = []; let itemsToFind = Object.values(data); myFilter.forEach((filterItem) => { if (itemsToFind.indexOf(filterItem.value) != -1) { matchedItems.push("matched"); } }); //check if everything matched if (matchedItems.length === keysToMatch) { tempArray.push(data); } }); console.log(tempArray); 

You can use normal for loop and array filter. Define a variable filteredArray and use for loop to iterate myFilter . During each iteration create a variable k whose value will be set to the filtered array. So at the first step the initial value of k will be the myArray and k will be filtered and the filtered value will be set to filteredArray . During second iteration and so on the value of k will be set to the first filtered array

 let myArray = [{ make: "Honda", model: "CRV", year: "2017" }, { make: "Toyota", model: "Camry", year: "2020" }, { make: "Chevy", model: "Camaro", year: "2020" } ] let myFilter = [{ field: "make", value: "Chevy", type: "string" }, { field: "year", value: "2020", type: "date" } ]; let filteredArray; for (let i = 0; i < myFilter.length; i++) { let k = filteredArray !== undefined ? filteredArray : myArray if (myFilter[i].field === 'make') { filteredArray = k.filter(item => item[myFilter[i].field] === myFilter[i].value) } else if (myFilter[i].field === 'year') { filteredArray = k.filter(item => item[myFilter[i].field] === myFilter[i].value) } } console.log(filteredArray) 

var tempArray = [];
const keysToMatch = myFilter.length;
let matchedItems = [];
myArray.forEach((data) => {
    matchedItems = [];
    let itemsToFind = Object.values(data);
    myFilter.forEach((filterItem) => {
        if (itemsToFind.indexOf(filterItem.value) != -1) {
            matchedItems.push("matched");
        }
    });
    //check if everything matched
    if (matchedItems.length === keysToMatch) {
        tempArray.push(data);
    }
});

console.log(tempArray);

This should theoretically work, but for some reason doesn't (returns an empty array). I'm hoping for some other reader's heads up to make it work! Feel free to edit.

 myArray = [{ make: "Honda", model: "CRV", year: "2017" }, { make: "Toyota", model: "Camry", year: "2020" }, { make: "Chevy", model: "Camaro", year: "2020" } ] myFilter = [{ field: "make", value: "Chevy", type: "string" }, { field: "year", value: "2020", type: "date" } ]; const myNewArray = myArray.filter((car) => myFilter.every((filter) => car[filter.field] === car[filter.value])); console.log(myNewArray); 

This might be a bit over complicated for what you need, but it works.

 myArray = [ { make: "Honda", model: "CRV", year: "2017" }, { make: "Toyota", model: "Camry", year: "2020"}, { make: "Chevy", model: "Camaro", year: "2020"} ] myFilter = [ { field: "make", value: "Chevy", type: "string" }, { field: "year", value: "2020", type: "date" } ]; //only return those that return true var newArray = myArray.filter(car => { var temp = true; //iterate over your filters for (var i = 0; i < myFilter.length; i++) { //if any filters result in false, then temp will be false if (car[myFilter[i].field] != myFilter[i].value) { temp = false; } } if (temp == true) { return true; } else { return false; } }); console.log(JSON.stringify(newArray)); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM