This is a hard one to explain, but here goes. I need to clean an array of 'path' strings where if a path has sub properties it not include the top level property. but only the child properties
E.g
[
'firstName',
'address',
'address.local.addressLine1',
'address.local.addressLine2',
'address.local',
]
Should become:
[
'firstName',
'address.local.addressLine1',
'address.local.addressLine2',
'address.local',
]
I have a fairly verbose function kind of working so far, but looking to see if there is a more elegant/better solution than this:
function cleanCollisions(array) {
var output = [];
// return [...new Set(array)];
var map = array.reduce(function(set, field) {
if (!Boolean(field)) {
return set;
}
////////////////
var rootKey = field.split('.')[0];
if(!set[rootKey]) {
set[rootKey] =[];
}
var count = field.split('.').length -1;
if(count) {
set[rootKey].push(field);
}
return set;
}, {})
for(const key in map) {
value = map[key];
if(value.length) {
output.push(value);
} else {
output.push(key);
}
}
////////////////
return output.flat();
}
CodePudding user response:
I'd first iterate over the array to extract the top property of all strings that have sub properties, then filter out all those top properties.
const input = [
'firstName',
'address',
'address.local.addressLine1',
'address.local.addressLine2',
'address.local',
];
const topLevelProps = new Set();
for (const str of input) {
const match = str.match(/^(.*?)\./);
if (match) {
topLevelProps.add(match[1]);
}
}
const output = input.filter(str => !topLevelProps.has(str));
console.log(output);
CodePudding user response:
A variation of the answer by CertainPerformance but using filter
and map
instead of regex:
const paths = [
'firstName',
'address',
'address.local.addressLine1',
'address.local.addressLine2',
'address.local',
];
const roots = paths.filter(p => p.includes('.')).map(p => p.split('.')[0]);
const cleansed = paths.filter(p => p.includes('.') || !roots.includes(p));
console.log(cleansed);