Marco Borges
Marco Borges

Reputation: 15

get highest element in a two dimensional array

i have this array:

const myArray = [["Cow", 3], ["Pig", 5], ["Pig", 10], ["Pig", 4], ["Chicken", 1], ["Cow", 1], ["Cow" , 12], ["Cow", 11], ["Chicken", 12]]

and want to turn into this: (only the highest of each one)

[ [ 'Pig', 10 ], [ 'Cow', 12 ], [ 'Chicken', 12 ] ]

but with my code i cant get the last one, i cant find why tho

const myArray = [["Cow", 3], ["Pig", 5], ["Pig", 10], ["Pig", 4], ["Chicken", 1], ["Cow", 1], ["Cow" , 12], ["Cow", 11], ["Chicken", 12]]

function getHighest() {

  var onlyHighest = [];

  myArray.sort(
    function(a,b) {
      if (a[0] == b[0])
       return a[1] < b[1] ? -1 : 1;
      return a[0] < b[0] ? 1 : -1;
    }
  );  

  myArray.forEach((a, i) => {
    var i = i+1;
    if (i < myArray.length) {
      if (a[0] != myArray[i][0]){
        onlyHighest.push([a[0], a[1]]);
      }
    }
  });

  return console.log(onlyHighest)
  //    [ [ 'Pig', 10 ], [ 'Cow', 12 ] ]
}

Upvotes: 0

Views: 49

Answers (3)

Cooper
Cooper

Reputation: 64100

How about a simple sort

function funk() {
  let a = [["Cow", 3], ["Pig", 5], ["Pig", 10], ["Pig", 4], ["Chicken", 1], ["Cow", 1], ["Cow", 12], ["Cow", 11], ["Chicken", 12]];
  let r = a.sort((a, b) => {
    return b[1] - a[1]
  })[0];
  Logger.log(r);
}

Execution log
12:37:11 PM Notice  Execution started
12:37:11 PM Info    [Cow, 12.0]
12:37:12 PM Notice  Execution completed

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 371019

Your

myArray.forEach((a, i) => {
  var i = i+1;
  if (i < myArray.length) {

is causing the problem and is pretty confusing. If the last sorted chunk of the array contains only 2 elements, that condition won't be fulfilled, so nothing from that chunk will be pushed.

A quick fix would be to unconditionally push the original element if it's the last one in the array.

myArray.forEach((a, i) => {
  if (i === myArray.length - 1) {

A better refactor would be to group the input into an object that keeps the largest value for each property, no sorting involved.

const myArray = [["Cow", 3], ["Pig", 5], ["Pig", 10], ["Pig", 4], ["Chicken", 1], ["Cow", 1], ["Cow" , 12], ["Cow", 11], ["Chicken", 12]]

const grouped = {};
for (const [prop, num] of myArray) {
  grouped[prop] = Math.max(num, grouped[prop] ?? -Infinity);
}
const onlyHighest = Object.entries(grouped);
console.log(onlyHighest);

Upvotes: 1

Barmar
Barmar

Reputation: 781974

Use an object to hold the current highest value for each animal. Loop through the array, replacing the value when it's higher than the value in the object.

const myArray = [["Cow", 3], ["Pig", 5], ["Pig", 10], ["Pig", 4], ["Chicken", 1], ["Cow", 1], ["Cow" , 12], ["Cow", 11], ["Chicken", 12]]

function getHighest(array) {
  let obj = {};
  array.forEach(([key, value]) => {
    if (key in obj) {
      if (value > obj[key]) {
        obj[key] = value;
      }
    } else {
      obj[key] = value;
    }
  });
  return Object.entries(obj);
}

console.log(getHighest(myArray));

Upvotes: 2

Related Questions