【问题标题】:Redux - Filter / Delete multiple items from array of objects. Items to be filtered given in another arrayRedux - 从对象数组中过滤/删除多个项目。要过滤的项目在另一个数组中给出
【发布时间】:2021-08-05 14:06:26
【问题描述】:

我有一个初始状态变量,它是一个对象数组,并且想要过滤/删除另一个数组中给出的多个对象,其中包含要在有效负载中过滤的对象的 id

const initialState = {
    data: [
        {
            name: "apple", 
            id: 1
        }, 
        {
            name: "orange", 
            id: 2
        }, 
        {
            name: "broccoli", 
            id: 3
        }, 
        {
            name: "spinach", 
            id: 4
        }, 
    ]
}

export default (state = initialState, { type, payload }) => {
    switch (type) {    
    case FILTER_ITEMS:
        //filteredArray = 
        return {
            ...state, 
            data: filteredArray
        }
}

我想从初始状态中筛选出没有有效载荷内数组中给定的 id 的项目

payload = {
   excludeIds = [2,4]
}

所以reducer运行后initialState应该改为:

state = {
    data: [
        {
            name: "apple", 
            id: 1
        }, 
        {
            name: "broccoli", 
            id: 3
        }, 
    ]
}

【问题讨论】:

    标签: javascript arrays reactjs redux react-redux


    【解决方案1】:

    使用Array.filter()Array.includes() 获取所有项目,其中id 未出现在排除数组中:

    const initialState = {"data":[{"name":"apple","id":1},{"name":"orange","id":2},{"name":"broccoli","id":3},{"name":"spinach","id":4}]}
    
    const state = initialState;
    const payload = {
      excludeIds: [2, 4]
    }
    
    const result = state.data.filter(o => !payload.excludeIds.includes(o.id))
    
    console.log(result)

    在减速器中:

    export default (state = initialState, { type, payload }) => {
        switch (type) {    
        case FILTER_ITEMS:
            const data = state.data.filter(o => !payload.excludeIds.includes(o.id))
            return {
                ...state, 
                data
            }
    }
    

    如果排除数组可能很大,您可以使用Set,因为从 Set 中获取项目的复杂度是 O(1):

    const initialState = {"data":[{"name":"apple","id":1},{"name":"orange","id":2},{"name":"broccoli","id":3},{"name":"spinach","id":4}]}
    
    const state = initialState;
    const payload = {
      excludeIds: [2, 4]
    }
    
    const exclude = new Set(payload.excludeIds)
    
    const result = state.data.filter(o => !exclude.has(o.id))
    
    console.log(result)

    【讨论】:

    • 最坏情况下的时间复杂度是 O(n^2),有没有更快的方法来做到这一点?
    • 我已经用基于集合的答案更新了答案。
    • 完美,这样效率更高。现在是 O(n)。转换为集合的开销有点小,但比 O(n^2) 快得多
    • O(n + m) 其中 m 是排除的长度(集创建)。
    【解决方案2】:

    你可以使用indexOf function的数组。

    filteredArray = state.data.filter(ele => payload.excludeIds.indexOf(ele.id) < 0 ? true : false)
    

    测试:

    const initialState = {
        data: [
            {
                name: "apple", 
                id: 1
            }, 
            {
                name: "orange", 
                id: 2
            }, 
            {
                name: "broccoli", 
                id: 3
            }, 
            {
                name: "spinach", 
                id: 4
            }, 
        ]
    }
    
    const payload = {
       excludeIds: [2,4]
    }
    
    filteredArray = initialState.data.filter(ele => payload.excludeIds.indexOf(ele.id) < 0 ? true : false)
    
    console.log(filteredArray)

    【讨论】:

    • 你的回答也很干净,刚刚接受了@OriDori的回答,因为它更有效率。你的时间复杂度是 O(n^2) vs O(n)
    • 另一个答案将其从数组更改为集合。一个集合使用哈希函数,所以查找是 O(1)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    相关资源
    最近更新 更多