I'm trying to filter the array:
const arr = [
{
id: '1',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-09-12T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '3',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
];
to get results:
const arr = [
{
id: '1',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-09-12T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '3',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
];
so, I need to filter the array in that way to stay with objects without duplicates, when an object has a duplicate, it should get only one with the largest modifiedTime.
I was trying to do this in that way:
arr.reduce((arr, el) => (((arr.find(({id}) => el.id === id)) || arr.push(el)), arr), [])
but in this way, it returns to me an array without objects with duplicates id but modifiedTime is not the largest.
Maybe someone will be able to suggest it to me?
CodePudding user response:
You have 3 cases :
- If the item is not in the array, simply push it
- If the item is already but has a smaller time : don't do anything
- If the item is already but has an higher time : replace the item with the new one
This can be done using the js splice method
const arr = [{
id: '1',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-09-12T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '3',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
];
console.log(
arr.reduce((acc, curr) => {
const index = acc.findIndex(x => x.id === curr.id)
if(index === -1) acc.push(curr)
else {
if(new Date(acc[index].modifiedTime) < new Date(curr.modifiedTime))
acc.splice(index, 1, curr)
}
return acc
}, [])
)
CodePudding user response:
Filter, Remove Duplicates, Results!
// sort by ID and Modified Time cols
const sortByIDandModifiedTime = (arr) => {
return arr.sort((a, b) => {
if (a['id'] != b['id']) // if not same ids then sort
return a['id'] - b['id'];
else // if same ids sort by modified time
return a['modifiedTime'] - b['modifiedTime'];
});
};
// Remove all Duplicates, uses the items ID
const removeDups = (arr) => {
let groupByID = arr.map(item=>{return [item.id,item];});
let mapGroup = new Map(groupByID);
let getMapvalues = mapGroup.values();
let decomposeIntoAnArray = [...getMapvalues];
return decomposeIntoAnArray;
}
// load data
let arr = [
{
id: '1',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-09-12T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '3',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
];
// remove dups using function
// sort first
let sortarr = sortByIDandModifiedTime(arr);
// then filter
let newarr = removeDups(sortarr);
// log output
console.log(newarr);
CodePudding user response:
You can use this approach
Basically filter()
will remove all duplicate objects by checking if the previously mapped array id
includes the current id
. For filtering duplicates, it uses includes()
's second parameter index with index 1
which will ignore the current object and all previous.
let arr = [
{
id: '1',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-09-12T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '3',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
];
const objIds = arr.map(mappedObject => mappedObject.id)
const filteredArr = arr.filter(({id}, index) => !objIds.includes(id, index 1))
console.log(filteredArr);
CodePudding user response:
"...but modifiedTime is not hte largest." => you have to add the implementation of the case where you find 2 objects with the same id, and decide which of them you need.
const arr = [
{
id: '1',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-09-12T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '2',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
{
id: '3',
modifiedTime: '2022-08-11T12:30:36.191Z',
modifiedUser: 'test'
},
];
const getHighestModifiedTime = (obj1, obj2) => obj1.modifiedTime.localeCompare(obj2.modifiedTime) > -1 ? obj1 : obj2
const res = arr.reduce((obj, el) => ({
...obj,
[el.id]: obj[el.id] ? getHighestModifiedTime(obj[el.id], el) : el
}), {});
console.log(res)
CodePudding user response:
You can do it by transforming the array into a object with id as keys and taking back the object values back as the new array
let o={}
arr.foreach((e){o[e.id]=e});
arr=Object.values(o);