如何通过对象键和值动态过滤数组?

3

我有一个包含订单细节的对象数组:


let filteredOrders = []; // output array

let orders = [
    {
        id: 1,
        name: "ORDER 1",
        material: "8756"
    },
    {
        id: 2,
        name: "ORDER 2",
        material: "4548"
    },
    {
        id: 3,
        name: "ORDER 3",
        material: "8756"
    },
    {
        id: 4,
        name: "ORDER 4",
        material: "5678"
    }
]

还有另一个对象中的过滤器:

let filters = {
    materials: {
        selected: ""
    },
    ids: {
        selected: ""
    }
}

在程序的某个时刻,一个或两个过滤器会接收到一个值,如果该值不为空""且不为"all",则必须对数组进行筛选。
例如:
filters.materials.selected = "8756";

预期输出:

filteredOrders  = [
    {
        id: 1,
        name: "ORDER 1",
        material: "8756"
    },
    {
        id: 3,
        name: "ORDER 3",
        material: "8756"
    }
]

或者:

filters.materials.selected = "8756";
filters.ids.selected = 3;

期望输出:

filteredOrders  = [
    {
        id: 3,
        name: "ORDER 3",
        material: "8756"
    }
]

筛选器必须是动态的。不能指定“键”。

我尝试过的方法:

for (var [key, value] of Object.entries(filters)) {
    filteredOrders = orders.filter(function(order) {
        if (filters[key].selected !== "all" && filters[key].selected !== "") {
            if (order[key.slice(0, -1)] == filters[key].selected) {
                console.error("ADD", order, order[key.slice(0, -1)], filters[key].selected); 
                return order;
            }
        }
    });
}

// EMPTY
if (filteredOrders.length < 1) filteredOrders = orders; 

输出结果非常奇怪,原因是:

filters.materials.selected = "8756";
filters.ids.selected = 3;

filteredOrders数组有3个订单 -> ids: 2, 3, 3 (重复的“3”)


为什么在过滤器键名中要加上额外的“s”? - cmgchess
@cmgchess 在实际中,过滤器对象具有额外的键和值,用于在前端进行动态渲染。 - Anna
2个回答

3
如果您的筛选器与搜索字段名称相同,那么这将更容易。 然后您可以像下面这样做:

let filteredOrders = []; // output array

let orders = [
    {
        id: 1,
        name: "ORDER 1",
        material: "8756"
    },
    {
        id: 2,
        name: "ORDER 2",
        material: "4548"
    },
    {
        id: 3,
        name: "ORDER 3",
        material: "8756"
    },
    {
        id: 4,
        name: "ORDER 4",
        material: "5678"
    }
]

let filters = {
    material: {
        selected: "8756"
    },
    id: {
        selected: ""
    }
}

// Start with all the orders
filteredOrders = orders;

// Loop each filter
for (filter in filters) {
  // If a value is filled in, we start to filter
  if (filters[filter].selected) {
    // Check if order value is the same as filter value
    filteredOrders = filteredOrders.filter(o => o[filter] === filters[filter].selected)
  }
}

// Show result
console.log(filteredOrders)


0

试试这个。

//loop the filter array
for (var [key, value] of Object.entries(filters)) {
    //get the data that is equal to the value from the filter 
    let filtered = orders.filter(function(order) {  
    if (order[key.slice(0, -1)] == value.selected) {
            return order;
        }
    });

    //push unique data to filteredOrders
    if (filtered && filteredOrders.filter(i => i[key.slice(0,-1)] == value.selected).length == 0) {
        filteredOrders.push(...filtered);
    }
}
console.log(filteredOrders);

我给这个点了踩,因为根本没有任何解释。你不必解释每一行,但是一些注释会很好 :) - Wimanicesir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接