- Generally, you want to separate printing from logic. Have your function return the third biggest instead of printing it, and print the return value. This allows you to include the function in a larger project without needing to make any changes.
- https://softwareengineering.stackexchange.com/q/364086 and https://stackoverflow.com/q/34361379/2336725 recommend
function f(arr) {}
instead of const f = (arr) => {}
. But f
is a terrible name for a function. Let's change it to thirdBiggest
.
- There's no real point to the
Math.min
at the end. You know that big0
is the biggest, big1
is the biggest after that, and big2
the biggest after that. Lets just return big2
.
- You never change the
big#
values, so they should be constants. But it would be better to reuse the big#
and index#
variables. I'm going to rename them to big
and bigIndex
.
- But now we see that we're repeating the exact same steps three times. Let's move that into a for loop.
- We might as well use an array spread instead of
.apply
secureArr
implies some sort of security consideration, which I'm not seeing. If you're just wanting to not modify the original, lets call it a copy.
Here's where we are now:
let array = [442, 93, 3, 5, 30, 10];
function thirdBiggest(arr) {
let arrCopy = [...arr];
let big, bigIndex;
for ( let i = 0 ; i < 3 ; i++ ) {
big = Math.max(...arrCopy);
bigIndex = arrCopy.indexOf(big);
arrCopy.splice(bigIndex, 1);
}
return big;
}
console.log(thirdBiggest(array));
- You specifically mentioned fewer lines. This is not usually a good metric. If that's all you want, then you should go with Bens Steves' approach and your function will be two lines long. But it will be measurably slower for large arrays.
- "third biggest" is a bit arbitrary, and now that we have a loop, we can see that it's not hard to turn that into a parameter. Let's do that, and change
thirdBiggest
into nthBiggest
.
- The usual approach for this problem is that you go through the array once, and keep track of the highest values you've seen so far. If you see a new highest value, it pushes the bottom one off of the list. That ends up being:
function nthBiggest(arr,n) {
// start with the front of the array
let biggestValues = arr.slice(0,n);
biggestValues.sort( (a,b) => a-b );
// now look through the rest of the array
arr.slice(n).forEach( (value) => {
if ( value > biggestValues[0] ) {
biggestValues.shift();
let valueIndex = biggestValues.findIndex( (big) => big>value );
if ( valueIndex >= 0 ) {
biggestValues.splice(valueIndex,0,value);
} else {
biggestValues.push(value);
}
}
});
return biggestValues[0];
}
console.log(nthBiggest(array,3));
That's more lines than your original version, but should be the fastest.