miodus miodus - 23 days ago 9
Javascript Question

return last occurrence of name (many names) in an array of objects

Given the following data source:

[
{
"Username" : "Patrick",
"Time" : "08:01:32",
"Status" : "log in"
},
{
"Username" : "Patrick",
"Time" : "08:34:31",
"Status" : "idle"
},
{
"Username" : "Patrick",
"Time" : "08:52:10",
"Status" : "meeting"
},
{
"Username" : "Patrick",
"Time" : "10:07:52",
"Status" : "daily tasks"
},
{
"Username" : "Patrick",
"Time" : "12:00:11",
"Status" : "lunch"
},
{
"Username" : "Mark",
"Time" : "07:40:32",
"Status" : "log in"
},
{
"Username" : "Mark",
"Time" : "08:54:31",
"Status" : "meeting"
},
{
"Username" : "Mark",
"Time" : "09:52:10",
"Status" : "idle"
},
{
"Username" : "Mark",
"Time" : "10:07:52",
"Status" : "daily tasks"
},
{
"Username" : "Mark",
"Time" : "12:30:11",
"Status" : "lunch"
}
]


How do I get the last occurrence of each name in this array in a simple way? I was thinking about the filter function however I'm not sure how to proceed on this. Any support or tip will be highly appreciated.

The expected outcome should be as follows:

[
{
"Username" : "Patrick",
"Time" : "12:00:11",
"Status" : "lunch"
},
{
"Username" : "Mark",
"Time" : "12:30:11",
"Status" : "lunch"
}
]

Answer Source

Using ES6, you can reduce the array into a map, and then spread the values back to an array:

const data = [{"Username":"Patrick","Time":"08:01:32","Status":"log in"},{"Username":"Patrick","Time":"08:34:31","Status":"idle"},{"Username":"Patrick","Time":"08:52:10","Status":"meeting"},{"Username":"Patrick","Time":"10:07:52","Status":"daily tasks"},{"Username":"Patrick","Time":"12:00:11","Status":"lunch"},{"Username":"Mark","Time":"07:40:32","Status":"log in"},{"Username":"Mark","Time":"08:54:31","Status":"meeting"},{"Username":"Mark","Time":"09:52:10","Status":"idle"},{"Username":"Mark","Time":"10:07:52","Status":"daily tasks"},{"Username":"Mark","Time":"12:30:11","Status":"lunch"}];


const result = [...data.reduce((m, o) => m.set(o.Username, o), new Map()).values()];

console.log(result);

In ES5 you can do reduce the the array to an object that will contain the unique items, and then map the object back to an array using Object#keys:

var data = [{"Username":"Patrick","Time":"08:01:32","Status":"log in"},{"Username":"Patrick","Time":"08:34:31","Status":"idle"},{"Username":"Patrick","Time":"08:52:10","Status":"meeting"},{"Username":"Patrick","Time":"10:07:52","Status":"daily tasks"},{"Username":"Patrick","Time":"12:00:11","Status":"lunch"},{"Username":"Mark","Time":"07:40:32","Status":"log in"},{"Username":"Mark","Time":"08:54:31","Status":"meeting"},{"Username":"Mark","Time":"09:52:10","Status":"idle"},{"Username":"Mark","Time":"10:07:52","Status":"daily tasks"},{"Username":"Mark","Time":"12:30:11","Status":"lunch"}];

var uniques = data.reduce(function(m, o) {
  m[o.Username] = o;
  
  return m;
}, Object.create(null));

var result = Object.keys(uniques).map(function(key) {
  return uniques[key];
});

console.log(result);