Reputation: 767
I have a js object array as below
[
[
{file: 'file1',
status: 'pending',
time: '2021-08-13 11:20:00'
},
{file: 'file2',
status: 'pending',
time: '2021-08-13 11:20:00'
}
],
[
{file: 'file1',
status: 'completed',
time: '2021-08-13 09:30:00'
},
{file: 'file2',
status: 'completed',
time: '2021-08-13 09:30:00'
}
],
[
{file: 'file3',
status: 'completed',
time: '2021-08-14 06:50:00'
}
]
]
And i need to filter the array based on the file field and remove the duplicated sub arrays. So the output should look like
[
[
{file: 'file1',
status: 'pending',
time: '2021-08-13 11:20:00'
},
{file: 'file2',
status: 'pending',
time: '2021-08-13 11:20:00'
}
],
[
{file: 'file3',
status: 'completed',
time: '2021-08-14 06:50:00'
}
]
]
What is the easiest way to do this. Can we use ES6 here?
Upvotes: 0
Views: 159
Reputation: 19986
Try using Array.reduce
.
Please see the code comments for logic.
const input = [
[
{ file: 'file1', status: 'pending', time: '2021-08-13 11:20:00' },
{ file: 'file2', status: 'pending', time: '2021-08-13 11:20:00' }
],
[
{ file: 'file1', status: 'completed', time: '2021-08-13 09:30:00' },
{ file: 'file2', status: 'completed', time: '2021-08-13 09:30:00' }
],
[
{ file: 'file3', status: 'completed', time: '2021-08-14 06:50:00' }
]
]
const output = input.reduce((acc, curr) => {
let isNodeExist = false;
/*
* Each node of the accumulator acc will be an array
* Which means the accumulator acc is an array of arrays
* The current node curr will also be an array
* So we have to verify the array curr has the same set present
* For that there should be a child node present in acc with the same length of curr
* Also the each name of curr should be there in that matching node
*/
acc.forEach((node) => {
isNodeExist = node.length === curr.length;
if (isNodeExist) {
curr.forEach((currNode) => {
isNodeExist = isNodeExist && (node.find((item) => item.file === currNode.file) !== undefined);
})
}
});
if(!isNodeExist) {
acc.push(curr);
}
return acc;
}, []);
console.log(output);
Upvotes: 2
Reputation: 13782
If you need to save just the first instance with the same group of names, this is a possible way:
const data = [
[
{file: 'file1',
status: 'pending',
time: '2021-08-13 11:20:00'
},
{file: 'file2',
status: 'pending',
time: '2021-08-13 11:20:00'
}
],
[
{file: 'file1',
status: 'completed',
time: '2021-08-13 09:30:00'
},
{file: 'file2',
status: 'completed',
time: '2021-08-13 09:30:00'
}
],
[
{file: 'file3',
status: 'completed',
time: '2021-08-14 06:50:00'
}
],
[
{file: 'file2',
status: 'completed',
time: '2021-08-14 06:50:00'
}
],
];
const filteredData = [];
const seenFiles = new Set();
for (const group of data) {
const fileNames = JSON.stringify(group.map(({ file }) => file).sort());
if (!seenFiles.has(fileNames)) {
seenFiles.add(fileNames);
filteredData.push(group);
}
}
console.log(filteredData);
Upvotes: 1