0

I have a initial state variable that is an array of objects and want to filter / delete multiple objects given in another array containing the id's of the objects to be filtered in the payload

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
        }
}

I want to filter items from the initialState that do not have the id's as given in the array inside the payload

payload = {
   excludeIds = [2,4]
}

So after the reducer runs the initialState should be changed to:

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

2 Answers 2

2

Use Array.filter() with Array.includes() to take all items, which id doesn't appear in excluded array:

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)

And in the reducer:

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
        }
}

You can use a Set if the array of excludes might be large, since the complexity of getting an item from a Set is 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)

Sign up to request clarification or add additional context in comments.

4 Comments

The worst case time complexity for this would be O(n^2), is there a faster way to do this?
I've updated the answer with a Set based answer.
Perfect, this is much more efficient. Its O(n) now. A little overhead of converting to a set but much faster than O(n^2)
O(n + m) where m is length of excluded (Set creation).
0

You can use indexOf function of array.

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

Tested:

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)

2 Comments

Your answer is very clean too, just accepted @OriDori's answer because it is more efficient. Your time complexity is O(n^2) vs O(n)
The other answer changed it from an array to a set. A set uses a hash function so lookups are O(1)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.