-2

I have a JavaScript array :

const arr = ['a', 'b', 1, 4, 6, 'John', 9, 91];

I want to only keep the integers and filter out the strings and characters. Is there any way to do it ? I tried with typeof() but it is not working. Thanks in advance.

Jyotirmoy Das
  • 15
  • 1
  • 6
  • Use `typeof`. Can you show your code so we can see why it's not working? – slebetman May 18 '22 at 06:46
  • 1
    ```const arr = ['a', 'b', 1, 4, 6, 'John', 9, 91]; console.log(arr.filter((x) => { if(typeof x === Number) { return x; } }))``` – Jyotirmoy Das May 18 '22 at 06:48
  • Oh. I see. You think `typeof` is a function? It is not. It is a keyword like `return` or `else`. See: https://jsfiddle.net/pf1x0sw7/ – slebetman May 18 '22 at 06:49
  • 1
    You can make it shorter: `arr.filter(Number)`; – Andy May 18 '22 at 06:52
  • @Andy that doesn't work for arrays containing `0` or `"42"` – Bergi May 18 '22 at 07:12
  • It works for the example in the question. @Bergi. – Andy May 18 '22 at 07:23
  • 1
    @Andy So does `return [1, 4, 6, 9, 91]`. Doesn't make a solution. – Bergi May 18 '22 at 18:24
  • @JyotirmoyDas - Unrelated to this question, but I wondered why you were getting that problem in your now-deleted question. I guess you figured it out since you deleted the question, but in case you didn't: https://stackoverflow.com/q/74558724/157247 – T.J. Crowder Nov 24 '22 at 09:53

4 Answers4

3

You can use Array.prototype.filter and filter out the items which are numbers using the typeof operator.

const 
  arr = ["a", "b", "1", 4, 6, "John", 9, 91],
  nums = arr.filter((a) => typeof a === "number");

console.log(nums);

Another approach

You can also do it coercing the items to a number. The strings which cannot be coerced to a number result in NaN, a falsy value in JS, and hence are filtered out.

const 
  arr = ["a", "b", 1, 4, 6, "John", 9, 91],
  nums = arr.filter(Number);

console.log(nums);

But note strings that can be coerced to numbers like "1", "123" etc will not get filtered out by the second approach.

And more importantly this approach would filter out all zeroes (0, "0") in the array as 0 is a falsy value in JS.

const 
  arr = ["1", "4", "6", 0, "0"],
  nums = arr.filter(Number);

console.log(nums);

Filtering Integers

You can also filter only integers using Number.isInteger

const 
  arr = ["1", 2, -3, 4.5],
  ints = arr.filter(Number.isInteger);

console.log(ints);

But note, this approach would not filter out numbers where the integral part of the number is equal to the number itself. In other words simply appending zeroes after the decimal point (like 1.00000) would not yield false when passed to isInteger.

const 
  arr = [1.0, 2.01],
  ints = arr.filter(Number.isInteger);

console.log(ints);
SSM
  • 2,855
  • 1
  • 3
  • 10
  • 1
    Also `Number` filters out the legitimate number `0` – Bergi May 18 '22 at 07:13
  • @Bergi Yeah, nice point, added that to the answer. – SSM May 18 '22 at 07:16
  • The "*floating point numbers that can be represented as integer*" bit doesn't really make sense. The input (number literal) `3.0000000000000001` simply is parsed to the floating point number `3`, since there is not enough precision to represent such a small fraction. This has nothing to do with `Number.isInteger`. – Bergi May 18 '22 at 18:27
  • @Bergi My interpretation of that line is, numbers that can be (**or has to be**) represented in the form of integer will yield `true` with `isInteger`. For ex: (1) `1.0` can be represented as an integer, so `Number.isInteger(1.0)` gives `true`. (2) Number `2.1` cannot be represented as an integer and there's enough precision as well, so `Number.isInteger(2.1)` gives `false`. (3) Lastly `3.0000000000000001` because of lack of precision becomes an Integer, hence `Number.isInteger(3.0000000000000001)` gives `true`. – SSM May 19 '22 at 04:31
  • @Bergi Or more simply, numbers whose integral part is equal to the number itself will yield `true` with `isInteger`. Something like `const isInteger = (n) => Math.trunc(n) === n`. – SSM May 19 '22 at 04:38
  • 1
    I just think the note is confusing, because the behaviour is not related to `Number.isInteger`. The `3.000…01` becomes an integer (in floating point representation) at parsing, it already *is* an integer when being passed to the function – Bergi May 19 '22 at 08:35
  • @Bergi Yeah, I completely get your point. The wording might *not* be accurate but the note is important because numbers like `1.0` yield `true`, but they are *not* integers when passed to the method. I guess the docs also wanted to mainly emphasize this, but in addition they also added the precision related numbers, which I agree has nothing to do with `Number.isInteger`. I've updated my answer, please feel free to make any required edits. – SSM May 19 '22 at 09:33
2

try this:

arr.filter((elem) => Number.isInteger(elem));

output = [1,4,6,9,91]
Alexander
  • 16,091
  • 5
  • 13
  • 29
1
   const arr = ['a', 'b', 1, 4, 6, 'John', 9, 91];

const number = arr.filter(item => typeof item === 'number')
console.log(number )

here the correct way

MarcoWriteCode
  • 113
  • 1
  • 5
0

You can also iterate over array values using for loop and check whether the number in condition and push in new array which will result in getting all the number values.

const arr = ['a', 'b', 1, 4, 6, 'John', 9, 91];
newArr=[];
for(let i=0;i<arr.length;i++){
/* console.log(arr[i]); */
if(Number(arr[i])){
newArr.push(arr[i]);
}
}

console.log(newArr);
Omer
  • 34
  • 4