4

I need to find max number then remove it from array.(only single instance)

let array is

a=[91,65,91,88,26]

I am finding max using Math.max()

k=Math.max(...a)

Now using filter() it

a=a.filter(e => e!=k);

But its filtering both the instances of max number.

How to resolve it?

YaSh Chaudhary
  • 2,027
  • 5
  • 31
  • 65

4 Answers4

2

Here are two simple ways to do it:

First way using splice()

a=[91,65,91,88,26];
a = a.sort();
a.splice(-1, 1);
console.log(a);

// Array [ 26, 65, 88, 91 ]

Second way using pop()

a=[91,65,91,88,26];
a = a.sort();
a.pop();
console.log(a);

// Array [ 26, 65, 88, 91 ]
Ryan Griggs
  • 1,919
  • 1
  • 21
  • 42
  • 1
    I'd suggest using `-1` as the start index, so that you don't need to first calculate the length of the array. `a.sort().splice(-1, 1);` – fubar Nov 27 '17 at 04:56
  • I changed the splice to use -1 index, and added the pop() method too for completeness. – Ryan Griggs Nov 27 '17 at 05:00
2

As you have discovered, .filter() iterates the entire array, testing each value against your filter function. That is not the task you have articulated.

The key to removing a single element is .splice(). Your task is simply to tell splice which item(s) to remove:

a.splice(a.indexOf( k ), 1);

Alternatively, you could remove the last index with:

a.splice(a.lastIndexOf( k ), 1);

In "human", arr.splice(k, n) reads "Starting at index k, remove the next n elements."

Of course, if you don't mind the overhead of sorting (or changing the item order!), then you can do something like:

a.sort().pop();

Which will sort the array, and then remove the final element -- which is also the largest.

hunteke
  • 3,309
  • 1
  • 4
  • 15
0

You could find the index of the element you want to remove and remove just that. Not writing Sort assuming you'd want to retain the order of the array.

So that would require using findIndex.

k=Math.max(...a)
i=a.findIndex(el => el === k)
newArray = [...a.slice(0, i), ...a.slice(i+1)]

Using array slice in the manner I've done also makes sure we don't change the initial array.
Although I would not advise using this for very large arrays.
You'd get best performance by writing your own function that does all of this.

Jeff P Chacko
  • 4,148
  • 3
  • 20
  • 29
  • If Math.max() and findIndex() have complexity O(n) each, then each slice() would have complexity O(n) also, as they would need to iterate through every element of the original array, copying to new array... so wouldn't that be O(4n)? The javascript sort() method has varying complexity based on browser, but we may be able to assume O(n log n). Then pop() should be O(1) as I assume it simply unlinks the last element or reduces the internal counter by 1. This would be much faster. your thoughts? see https://stackoverflow.com/questions/22614237/javascript-runtime-complexity-of-array-functions – Ryan Griggs Nov 27 '17 at 05:07
  • 1
    I completely agree with you. I've currently got this habit of favoring immutability. And preserving immutability is often important to make things more predictable in large applications. That said if we need more performance, I'm always open to rethinking my approach. :) – Jeff P Chacko Nov 27 '17 at 05:13
0

Here is a functional version of the task that doesn't mutate your original array. Please see the inline comments for an explanation.

const a = [91,65,91,88,26]

// return the max out of two numbers
const max = (x, y) => x > y ? x : y

const removeMax = a => {
  // find the largest value in the array with reduce
  const largest = a.reduce(max, 0)
  // get the first index of the largest number
  const index = a.indexOf(largest)
  // return a new array without the largest number
  return [
    ...a.slice(0, index),
    ...a.slice(index + 1)
  ]
}

console.log('before', a)

console.log('after', removeMax(a))
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
synthet1c
  • 5,543
  • 2
  • 15
  • 30