0

I have this array object:

0:
  id: "123123"
  cost: 100
  quantity: 2
1:
  id: "112233"
  cost: 100
  quantity: 5
2:
  id: "112233"
  cost: 100
  quantity: 0
3:
  id: "126233"
  cost: 100
  quantity: 0

What I want is to scan the whole object array and delete the ones with 0 quantity value. How do I do this with javascript?

4
  • What have you tried so far? Commented Jun 21, 2020 at 4:52
  • you could use a loop. many libs have map - reduce tricks too. Are you using any library? Commented Jun 21, 2020 at 4:53
  • 1
    stackoverflow.com/questions/15287865/… isn’t exactly the same question, but its top two answers apply. Commented Jun 21, 2020 at 4:54
  • stackoverflow.com/questions/16491758/… isn’t exactly the same question, but its answers apply too. Commented Jun 21, 2020 at 4:55

7 Answers 7

3

Using the function from my answer at remove objects from array by object property,

filterInPlace(array, item => item.quantity !== 0);

const filterInPlace = (array, predicate) => {
    let end = 0;

    for (let i = 0; i < array.length; i++) {
        const obj = array[i];

        if (predicate(obj)) {
            array[end++] = obj;
        }
    }

    array.length = end;
};

const arr = [
    {
        id: "123123",
        cost: 100,
        quantity: 2,
    },
    {
        id: "112233",
        cost: 100,
        quantity: 5,
    },
    {
        id: "112233",
        cost: 100,
        quantity: 0,
    },
    {
        id: "126233",
        cost: 100,
        quantity: 0,
    },
];

filterInPlace(arr, item => item.quantity !== 0);

console.log(arr);

  • This does modify the array in place. If you don’t need that, the Array#filter equivalent is probably better.

  • This is linear-time, constant space, whereas solutions based splice have a worse worst case(s). (@Hogan’s answer is also linear-time; this is the same idea as it, but with the loops merged.)

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

1 Comment

I don't know... I think it is one loop because the exit is based on the adding the two indexes together. Two loops makes it sound like O(N^2) or O(2N) when it is still O(N) --- thanks for the hat tip.
1

array.filter() creates new array with the filtered objects.

take a look at this:

const values = [
  {id: '123123', cost: 100, quantity: 2},
  {id: '112233', cost: 100, quantity: 5},
  {id: '112233', cost: 100, quantity: 0},
  {id: '126233', cost: 100, quantity: 0},
]

const filtered = values.filter((obj) => obj.quantity !== 0)

console.log(filtered)
// expected output: [ { id: '123123', cost: 100, quantity: 2 }, { id: '112233', cost: 100, quantity: 5 } ]

4 Comments

He specifically says he wants to scan an array and delete not create a new array.
@Hogan: A lot of people don’t realize there’s a difference, so the OP might not necessarily care.
@Ry- In my experience there is an expectation that answers do what the question asks -- not something else. Considering that filter is part of the standard API I think it more likely that a programmer would know what it did and be asking the question because that did not solve the problem. Why assume the questioner made a mistake?
@Hogan Imho it is a good thing to mention another way in answers because we try not to answer OP alone, but many users after them. Some of them might not know the API capability. Another reason: this might be an x/y problem.
0
let data = [
 {id: "123123",
  cost: 100,
  quantity: 2},
 { id: "112233",
  cost: 100,
  quantity: 5}, 
 { id: "112233",
  cost: 100,
  quantity: 0},
 {id: "126233",
  cost: 100,
  quantity: 0} 
];

let i =0;
 while (i < data.length) {
    if (data[i].quantity === 0) {
      data.splice(i, 1);
    } else {
      ++i;
    }
  }

console.table(data);

Comments

0

Just iterate over the elements of the array and check for the value of quantity and delete with splice:

let arr = [
    {
        id: "123123",
        cost: 100,
        quantity: 2,
    },
    {
        id: "112233",
        cost: 100,
        quantity: 5,
    },
    {
        id: "112233",
        cost: 100,
        quantity: 0
    },
    {
        id: "126233",
        cost: 100,
        quantity: 0
    }
];
let len = arr.length;
for( let i = 0; i < len; i++) {
    if(arr[i]['quantity'] === 0){
        arr.splice(i--,1);
        len--;
    }
}
console.log(arr);

output:

[
  { id: '123123', cost: 100, quantity: 2 },
  { id: '112233', cost: 100, quantity: 5 }
]

Comments

0

I usually don't recommend mutating the input itself. But since you have this requirement, Just created this utility in order to fulfil your requirement.

let data = [
  { id: '123123', cost: 100, quantity: 2 },
  { id: '112233', cost: 100, quantity: 5 },
  { id: '112232', cost: 100, quantity: 0 },
  { id: '112234', cost: 200, quantity: 0 },
  { id: '112235', cost: 400, quantity: 1 }
]

const indexesToBeRemoved = [];
data.forEach((d, index) => {
  if(d.quantity === 0) indexesToBeRemoved.push(index)
})

const length = indexesToBeRemoved.length;
for(let i=length-1; i>=0; i--) {
  data.splice(indexesToBeRemoved[i],1)
}

console.log(data)

One another way of fulfilling your requirement.

let data = [
  { id: '123123', cost: 100, quantity: 2 },
  { id: '112233', cost: 100, quantity: 5 },
  { id: '112232', cost: 100, quantity: 0 },
  { id: '112234', cost: 100, quantity: 0 },
  { id: '112235', cost: 100, quantity: 1 }
]

let numberOfItemsToBeRemoved = 0;

data.forEach((d, index) => {
  if(d.quantity === 0) {
    data.unshift(...data.splice(index, 1))
    numberOfItemsToBeRemoved++;
  }
})

console.log("deleted items: ", data.splice(0, numberOfItemsToBeRemoved))
console.log(data)

Hope this helps.

4 Comments

I don't think this works... the array changes every time you do the splice. Did you test this?
@Hogan, Yes I have tested this and it works. Please do let me know if there's any issue with the existing one.
It won't work -- just try a more complicated case. For example have an item to be deleted as the 2nd item and the last item. Then you will throw an exception. or try and delete something past the end of the array.
I tried the scenario For example have an item to be deleted as the 2nd item and the last item and is working as expected. Please have a look here
-1

If you really have an array you can't delete -- most libraries that do this functionally will create a new object. If you want to "delete" items what you really have to do is move other elements down to over write the ones you no longer want.

So I would use the following steps.

  1. Check to see if the filter item appears at all -- if it does not there is nothing to do.

  2. If it does appear then then let n be the index of the first item to filter. next is the next item out after it.

    loop (index from n to index+next < size of array)
     while next is an item to filter increase next by 1
     copy from next to index
     --> increase next by 1 and back to start of loop
    

Comments

-1

first get element indexes and then delete them

arr=[{
  'id': "123123",
  cost: 100,
  quantity: 2
},
{
  id: "112233",
  cost: 100,
  quantity: 5
},
{
  id: "112233",
  cost: 100,
  quantity: 0
},
{
  id: "126233",
  cost: 100,
  quantity: 0
}
]
index=[]
arr.forEach(x => {
 if (x.quantity==0) index.push(arr.indexOf(x))
});

    i=0
index.forEach(x=>{
  arr.splice(x+i,1)
  i--
})
console.log(arr)

9 Comments

This is working on the example by coincidence. arr.indexOf(x) is the wrong operation and produces -1, which splices off the last element. If you replace that with x, it still won’t work, because splicing an element out changes the indexes of future elements.
you get the element indexes and then start deleting -- after the first delete they are invalid. this solution is very broken.
I have updated the solution do you think this code will work?
No. You can't have the check in another loop -- there will always be ways it will fail because the location change with ever splice.
… yes. I do think this code will work. :D But you can also do the splices directly instead of building an array first.
|

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.