javascriptmethodsshortest

One Line Task: Check Range - CodeWars (using JavaScript's methods)


Task

You're given an array of integers a and two integers x and y. Count the number of elements in the array such that `x ≤ a[i] ≤ y, where i is the 0-based index of the element.

Code Limit

Less than 48 characters.

Example

For a = [2, 5, 6, 7, 1, 3, 4, 11, 56, 49], x = 1 and y = 7, the output should be 7.

elements 2, 5, 6, 7, 1, 3, 4 should be counted.

I have tired filter, reduce and can't think any other possible way without making it longer than 48 characters.

Here's through using filter

checkRange=(a,x,y)=>a.filter(i=>i>=x&&i<=y).length

Using reduce

checkRange=(a,x,y)=>a.reduce((c,i)=>i>=x&&i<=y?++c:c,0);

Function call example

a =[95,92,27,55,55,20,40,8,7,45,87,14,44,35,64,84,95,85,69,47,53,49,95,54,97,7,67,31,76,97,7,24,82,61,10,34,34,85,66,96,65,2,84,4,68,74,46,50]
    x = 64
    y = 76

checkRange(a,x,y) // Expected: 8

I'm getting over 50+ characters so far....and I need to reduce them to 47.

Some Hints so far...

I have gotten these from https://www.codewars.com/kata/one-line-task-check-range/discuss/javascript


Solution

  • This one passes all the test on codewars (thanks @ggorlen for the hint):

    a = [2, 5, 6, 7, 1, 3, 4, 11, 56, 49];
    x = 1;
    y = 7;
    checkRange=(a,x,y)=>a.map(v=>i+=x>v==v>y,i=0)|i;
    console.log(checkRange(a,x,y));

    It works by setting up a counter (i) using the thisValue parameter to Array.map which replaces all the values in a with the count of how many values pass the test x>v==v>y (by using i+=x>v==v>y - in an arithmetic context a boolean value is considered to be 1 (true) or 0 (false)). So for the sample array, we get [1,2,3,4,5,6,7,7,7,7] (although the only part we are actually interested in is the value of i). The test computes whether x>v and v>y are both the same, which can only be true when they are both false, which implies x<=v and v<=y which is our desired end condition. Finally the |i attempts to bitwise or an array with i which is equivalent to just i since an array in that context == NaN, and NaN bitwise OR'ed with a number returns that number.

    Note that in the special case where a has one number in it, the output from map will be either [0] or [1] and this will successfully be converted to 0 or 1 for the purpose of the bitwise OR. In this case that number will be the same as i (since the output of map is an array of i values), so again the result of the bitwise OR will be i as desired. For example:

    a = [2];
    x = 1;
    y = 7;
    checkRange=(a,x,y)=>a.map(v=>i+=x>v==v>y,i=0)|i;
    console.log(checkRange(a,x,y));
    
    a = [49];
    console.log(checkRange(a,x,y));