skip to Main Content
const arr = [6, 3, 1, 4, 1];

const removeSmallestNum = function(arr) {
    const copy = arr.slice();
    const minNum = copy.indexOf(Math.min(...copy));
    console.log(minNum);
    return copy.filter(num => copy.indexOf(num) !== minNum);
}

const result = removeSmallestNum(arr);
console.log(result)

What was required was to remove just 1 smallest number. I wrote code that removes more then one (if they are same) How is .filter removing second "1" when "minNum"(index of lowest number) is 2 ? It looks like it’s passing 2 times through array, but it’s not. Can someone break it down for me.

This is the code that works in CodeWars
Instead of ".filter"

return copy.splice(minNUm, 1)); // This returns just first smallest element.

5

Answers


  1. minNum gets calculated as 2 because the smallest number is 1, at index 2 (ie the third element in the array).

    And then this filter does this:

    return copy.filter(num => copy.indexOf(num) !== minNum);

    It finds the FIRST index of the number at that point in the array, and check if it’s the same index as minNum, and if it is it excludes it. So the first 1 it sees has a first index of 2, so it filters it out, and the second 1 it sees also has a first index of 2 (because the first index of the value 1 is still 2), so it filters that out too.

    What you want to do instead of check if the current index is minNum, copy.filter((num, index) => index !== minNum)

    Login or Signup to reply.
  2. You probably wanted to check if index of item is equal to index of smallest number

    const arr = [6, 3, 1, 4, 1];
    
    const removeSmallestNum = function(arr) {
        const copy = arr.slice();
        const minNumIndex = copy.indexOf(Math.min(...copy));
        console.log(minNumIndex);
        return copy.filter((num, index) => index !== minNumIndex);
    }
    
    const result = removeSmallestNum(arr);
    console.log(result)
    Login or Signup to reply.
  3. You can calculate the min first, then filter on that. There is no need to copy the array, since Array.prototype.filter already returns a copy.

    const
      removeSmallestNum = (arr) =>
        ((min) => arr.filter((n) => n !== min))
        (Math.min(...arr)),
      input = [6, 3, 1, 4, 1],
      output = removeSmallestNum(input);
    
    console.log(...output); // [6, 3, 4]

    The IIFE above, can be expanded to:

    const removeSmallestNum = (arr) => {
      const min = Math.min(...arr);
      return arr.filter((n) => n !== min);
    };
    
    Login or Signup to reply.
  4. alternative if I am allowed to sort.

    const arr = [6, 10, 3, 1, 4, 1];
    
    const removeSmallestNum = arr => [...
      new Set(arr.slice(0).sort((a,b)=>a-b)) // sort and remove dupes 
    ].slice(1); // return result from second entry onwards
    
    const result = removeSmallestNum(arr);
    console.log(result);
    Login or Signup to reply.
  5. If you want to modify the original array, instead of producing a copy of it with the elements removed, you can do this one-liner:

    const arr = [6, 3, 1, 4, 1]
    
    arr.reduceRight((m,c,i) => (c===m && arr.splice(i,1), m), Math.min(...arr))
    
    console.log(arr)

    What this does is visit every element of the array, starting with the last. This means that when we delete items, it does not affect our position within the array as we continue iterating over it.

    We take advantage of the fact that reduceRight allows us to calculate and store an initial value in the accumulator of the reduce operation, which allows us to compact this to a one-liner.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search