0

I'm trying to get the highest value of my object by ID and date. To explain better, this is my array:

[  
   {  
      "id":"6",
      "date":"201901",
      "value":"1"
   },
   {  
      "id":"6",
      "date":"201901",
      "value":"12"
   },
   {  
      "id":"6",
      "date":"201901",
      "value":"123"
   },
   {  
      "id":"6",
      "date":"201901",
      "value":"1231"
   },
   {  
      "id":"6",
      "date":"201902",
      "value":"4"
   },
   {  
      "id":"6",
      "date":"201902",
      "value":"45"
   },
   {  
      "id":"5",
      "date":"201902",
      "value":"56"
   },
   {  
      "id":"5",
      "date":"201902",
      "value":"46"
   }
]

I'm trying to get this return (Filtering the highest value by id and date):

[  
    {  
      "id":"6",
      "date":"201901",
      "value":"1231"
    },       
    {  
      "id":"6",
      "date":"201902",
      "value":"45"
    },
    {  
      "id":"5",
      "date":"201902",
      "value":"56"
    }       
]

In my code, I'm using map and filter but not works:

let resultados = array

array.map(item => {
  resultados.filter(itemFilter => {
    if(item.id == itemFilter.id && item.date == itemFilter.date){
      if(itemFilter.value > item.value){
        return itemFilter.value
      }
    }
  })
})

An similar solutis is this

Someone can help me?

Zkk
  • 741
  • 13
  • 29
  • Not sure if it's just me but, "_To explain better_..." - nope, still doesn't make sense. So you want to get the highest "value" for each "date" **for** each id? – Lewis Apr 01 '19 at 15:15

2 Answers2

1

You could take a Map with a combined key of the wanted keys for grouping. Then take the greater value.

var data = [{ id: "6", date: "201901", value: "1" }, { id: "6", date: "201901", value: "12" }, { id: "6", date: "201901", value: "123" }, { id: "6", date: "201901", value: "1231" }, { id: "6", date: "201902", value: "4" }, { id: "6", date: "201902", value: "45" }, { id: "5", date: "201902", value: "56" }, { id: "5", date: "201902", value: "46" }],
    result = Array.from(data
            .reduce((m, o) => (key =>    
                !m.has(key) || m.get(key).value < o.value
                    ? m.set(key, o)
                    : m
            )(['id', 'date'].map(k => o[k]).join('|')), new Map)
            .values()
        );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • I enjoyed your example, I saw that it works but a hand got a bit complicated for me, I'll look in the documentation item by item, thanks for the help! – Zkk Apr 01 '19 at 22:30
0

You can use Array.prototype.reduce :

yourArray.reduce( (accumulator, currentItem) => {
    var previouslyGreatestItem = accumulator.find(item => item.id == currentItem.id && item.date == currentItem.date);
    if (!previouslyGreatestItem) {
        accumulator.push(currentItem);
    } else if (previouslyGreatestItem.value < currentItem.value) {
        previouslyGreatestItem.value = currentItem.value;
    }
    return accumulator;
}, []);

var yourArray = [{"id":"6","date":"201901","value":"1"},{"id":"6","date":"201901","value":"12"},{"id":"6","date":"201901","value":"123"},{"id":"6","date":"201901","value":"1231"},{"id":"6","date":"201902","value":"4"},{"id":"6","date":"201902","value":"45"},{"id":"5","date":"201902","value":"56"},{"id":"5","date":"201902","value":"46"}];

var result = yourArray.reduce( (accumulator, currentItem) => {
 var previouslyGreatestItem = accumulator.find(item => item.id == currentItem.id && item.date == currentItem.date);
 if (!previouslyGreatestItem) {
  accumulator.push(currentItem);
 } else if (previouslyGreatestItem.value < currentItem.value) {
  previouslyGreatestItem.value = currentItem.value;
 }
 return accumulator;
}, []);

console.log(result);
Aaron
  • 24,009
  • 2
  • 33
  • 57
  • Thank you so much! Good to know that in the logic of `if`, was in the way more or less certain – Zkk Apr 01 '19 at 22:27