Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS: Filter array of objects by max value per category

What is most efficient / elegant way to achieve sql-like filtering effect. I want to filter them and get only that objects which are max value in some group.

This is my code, it works but probably it's not best way:

uniqueValues = (arr) => [...new Set(arr)];
getMaxTimeOf = (arr) => Math.max(...arr.map(o => o.timeStamp), 0);
selectorName = (name) => (obj) => obj.name === name;
selectorTime = (time) => (obj) => obj.timeStamp === time;
getGroup = (obj, selector) => obj.filter(selector)

onlyLastChangedFrom = (history) => {
const uniqueNames = uniqueValues(history.map(o => o.name))
let filtered = []
 uniqueNames.forEach(name => {
  const group = getGroup(history, selectorName(name))
  const groupLastTime = getMaxTimeOf(group)
  const lastChange = getGroup(group, selectorTime(groupLastTime))
  filtered.push(lastChange[0])
 });
 return filtered
}   
onlyLastChangedFrom(history)
    // Input:
    [ { name: 'bathroom',
        value: 54,
        timeStamp: 1562318089713 },
      { name: 'bathroom',
        value: 55,
        timeStamp: 1562318090807 },
      { name: 'bedroom',
        value: 48,
        timeStamp: 1562318092084 },
      { name: 'bedroom',
        value: 49,
        timeStamp: 1562318092223 },
      { name: 'room',
        value: 41,
        timeStamp: 1562318093467 } ]

    // Output:
    [ { name: 'bathroom',
        value: 55,
        timeStamp: 1562318090807 },
      { name: 'bedroom',
        value: 49,
        timeStamp: 1562318092223 },
      { name: 'room',
        value: 41,
        timeStamp: 1562318093467 } ]
like image 256
moraviec Avatar asked Jul 05 '19 10:07

moraviec


People also ask

How to filter an array of objects in JavaScript?

Filter an Array of Objects in JavaScript. JavaScript arrays have a filter () method that let you create a new array containing only elements that pass a certain test. In other words, filter () gives you a new array containing just the elements you need.

How to get MAX VALUE in array of objects in JavaScript?

Use inbuilt method Math apply (), map (), reduce () to get the max value in Array of objects in JavaScript. The Array object lets you store multiple values in a single variable. Ways to get max value in Array of objects:- Using apply () and map () method

What is the syntax of the filter () method in JavaScript?

The following illustrates the syntax of the filter () method: The filter () method creates a new array with all the elements that pass the test implemented by the callback () function. Internally, the filter () method iterates over each element of the array and pass each element to the callback function.

How does the array filter () method work?

The filter () method accepts two named arguments: a callback function and an optional object. Like other iterative methods of the Array object such as every (), some (), map () and forEach (), the callback function has the following form:


1 Answers

Reduce the array to an object, using the name property as the key. For each item, check if the item that exists in the accumulator has a higher value than the current item, and if not replace it with the current item. Convert back to an array with Object.values():

const arr = [{"name":"bathroom","value":54,"timeStamp":1562318089713},{"name":"bathroom","value":55,"timeStamp":1562318090807},{"name":"bedroom","value":48,"timeStamp":1562318092084},{"name":"bedroom","value":49,"timeStamp":1562318092223},{"name":"room","value":41,"timeStamp":1562318093467}]

const result = Object.values(arr.reduce((r, o) => {
  r[o.name] = (r[o.name] && r[o.name].value > o.value) ? r[o.name] : o

  return r
}, {}))

console.log(result)
like image 52
Ori Drori Avatar answered Oct 13 '22 01:10

Ori Drori