A solution to Basic Algorithm Scripting: Return Largest Numbers in Arrays

A solution to Basic Algorithm Scripting: Return Largest Numbers in Arrays
0

So I came up with a solution that I haven’t seen elsewhere for this problem and thought I’d share it, and if I’m wrong and it is elsewhere someone can correct me.

function largestOfFour(arr) {
  for (let subarr in arr) {
    arr.splice(subarr, 1, Math.max(...arr[subarr]));
  }
  return arr;
}

largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Edit: I hadn’t thought about how splice would cause the indexes to reorganize after each one, thanks @RandellDawson! Here is my updated code after @luishendrix92 tip about the .map() method which I hadn’t heard of before.

function largestOfFour(arr) {
 var n = 0;
 arr.map(function(group){
   arr[n++] = Math.max(...group);
 });
 return arr;
}

let result = largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

(Last?) Edit: Thank you @ieahleen for pointing out that I forgot to return the value from the inner function, and @JivkoJelev91 for inspiring me to do some more research on arrow functions. I learned a good bit from this site. This solution by @JivkoJelev91 is definitely my favorite:

return arr.map(grp => Math.max(...grp));
1 Like

Its good but two questions,
you mutate the original, its not mentioned in the challenge but I thought id mention it.
What do you mean when you say its ‘fairly efficient’. If I say n=one million isnt it still the same as my solution:

function largestOfFour(arr) {
  let holder=[]
  for (let i=0; i<arr.length; i++){
      holder.push(arr[i][0])
          //console.log(holder[i])
    for (let j=0; j<arr[i].length; j++){
        if (holder[i]<arr[i][j]){
          holder.splice(i,1,arr[i][j]);
        }
    }
  }
  return holder;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

Where both solutions are basically O(n)^2, what does math.max do thats so special? it still must need to go through and look at each item, so it will still take O(n) where n=number of elements your passing to math.max? besides being more concise I want to know why your solution is better time/space than mine

I only meant that it was visibly cleaner to look at really, and was happy that I was able to come up with a solution at all since I’d been having difficulty on some of these Algorithm challenges. Calling it fairly efficient wasn’t the right way to phrase it I guess.

I tested each solution and found that they both alternate from taking <1ms to 2ms to run so time wise the solutions are basically the same. This is how I tested it, not sure if it’s the best way:

let start = new Date().getTime();
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
let end = new Date().getTime();
console.log('Time: ', end - start);

Essentially the code does the same thing, it’s really down to personal preference on how to go about it. Personally I always look for ways to condense my code down to fewer lines that I have to look at. I can imagine one downside of that is not being able to test for bugs as easily though, I just thought of that.

Splice has additional overhead that you are not seeing. It has to completely reorganize the indexes of array after each splice.

2 Likes

I agree that the usage of splice is immensely unnecessary here. Not to mention it has to move around stuff to accommodate the vacant spaces with the rightmost items.

The use of Math.max(...) is great here. What you need is either a for that re-assigns the max value to the current index, or a .map

1 Like

Is this right?

arr.map(function(group){
    Math.max(...group);
});

It doesn’t return an array nevermind

It doesn’t return an array because you’re not returning anything in the group function. Simply put return before your Math.max

1 Like

It was returning each one as a number. I changed it to this and it worked:

function largestOfFour(arr) {
  var n = 0;
  arr.map(function(group){
    arr[n++] = Math.max(...group);
  });
  return arr;
}

You don’t need this counter. Just return:

return arr.map(grp => Math.max(...grp));
1 Like

you are missing a return statement…
return Math.max(...group) will work

1 Like

I think I just started to understand something better after looking into arrow functions. So this:

return arr.map(grp => Math.max(...grp));

Is like a shorter way of doing this:

return arr.map(function(group){ return Math.max(...group); });

right?

I see I was forgetting to return a value from the function inside the map method before now.

1 Like

I completely forgot about needing to return a value from that inner function, thank you!