-1

I'm trying to solve an exercise where I need to create the function cleanArray and remove various items from an array. This is as far as I could get

function cleanArray(arr) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === null || 0 || "" || false || undefined) {
            arr.splice(i, 1);
            return arr
        }
    }
}

But this only filters out null for me. I've tried putting the items to remove in a separate array or going one by one, but then it either returns undefined or only filters out the 0 even when it's not the first item to remove.

I've seen other answers where people use filter or indexOf but I want to see if there's a way to do it with splice. Is it not possible to use the logical operators here?

azibom
  • 1,769
  • 1
  • 7
  • 21
  • https://stackoverflow.com/questions/4728144/check-variable-equality-against-a-list-of-values – General Grievance Feb 15 '21 at 16:34
  • comparisons have to be made as every time you do different check: you should read it as: "if `arr[i] === null`, or `arr[i] === 0`...or `arr[i] === undefined`; in all these cases do this..." – Don Diego Feb 15 '21 at 16:40
  • Duplicate of [Javascript: The prettiest way to compare one value against multiple values](https://stackoverflow.com/questions/9121395/javascript-the-prettiest-way-to-compare-one-value-against-multiple-values), but the unconditional `return` is still a problem. You can replace your entire code by `arr.filter(Boolean)`. Better target: [Remove all falsy values from an array](https://stackoverflow.com/a/32906951/4642212). – Sebastian Simon Feb 15 '21 at 16:43
  • @azibom What’s the point of your [edit suggestion](https://stackoverflow.com/review/suggested-edits/28329532)? Please see [Should we approve suggested edits that change `\`\`\`` to four spaces code formatting or vice versa?](https://meta.stackoverflow.com/q/378962/4642212). – Sebastian Simon Feb 15 '21 at 16:50

3 Answers3

0

This is not the way you make multiple comparisons. Your if condition can be written as:

arr[i] === null || 0 === 1 || "" === 1 || false === 1 || undefined === 1

Now it is clear why it doesn't work, right? You need to compare arr[i] to every one of these values:

function cleanArray(arr) {
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] === null || arr[i] === 0 || arr[i] === "" || arr[i] === false || arr[i] === undefined) {
      arr.splice(i, 1);
      return arr
    }
  }
}

Note: this approach probably won't work. Since you are removing elements from your array (and hence it is getting shorter and shorter), once an element is removed, you will be in the wrong index, and by the time you reach the end of your loop, you will encounter undefined index errors. Finally, move your return statement out of the loop.

I suggest If you want to stay away from Array.filter(), I suggest creating a new array and only pushing in the values you want:

function cleanArray(arr) {
  var newArr = [];
  for (var i = 0; i < arr.length; i++) {
    if (arr[i] === null || arr[i] === 0 || arr[i] === "" || arr[i] === false || arr[i] === undefined) {
      continue;
    } else {
      newArr.push(arr[i]);
    }
  }
  return newArr;
}
Wais Kamal
  • 5,858
  • 2
  • 17
  • 36
0

You could simplify this doing two simple steps.

  1. Create a function to verify if a primitive value is falsy
  2. Using a filter or reducer to isolate those values from the source array

Example:

const array = [1,2,"", null, undefined, 3, "4", true, 5, false, "6"]

const isFalsy = value => !!value === false

// this one is just to make the code more readable
const isTrully = value => !isFalsy(value)

const trullyValues = array.reduce((a, c) => isFalsy(c) ? a : [...a, c], [])

// will return the same from above
const filteredyTrullyValues = array.filter(isTrully)
Jan Cássio
  • 2,076
  • 29
  • 41
  • "I want to see if there's a way to do it with splice" – Wais Kamal Feb 15 '21 at 16:47
  • Why? `splice` is suitable for changes in your indexes and it mutates the source array. Also, it's more complex and less performant. Read your problem again and try to resolve by the simple way first. In a real world situation, you will introduce more problems by doing a filter operation using a `splice` instead of using `reduce` or `filter`. – Jan Cássio Feb 15 '21 at 17:03
0

This will be enough:

if (!arr[i]) {
  arr.splice(i, 1);
  return arr
}

Because null || 0 || "" || false || undefined are evaluated to false.

lissettdm
  • 12,267
  • 1
  • 18
  • 39