Reputation: 281
This is a smaller version of the array i have but it has the same structure
with const arr below, i want to create 2 new arrays with unique values that are sorted in ascending order
const arr = [{
tags: ['f', 'b', 'd'],
weight: 7,
something: 'sdfsdf'
},
{
tags: ['a', 'b', 'c', 'd', 'e'],
weight: 6,
something: 'frddd'
},
{
tags: ['f', 'c', 'e', 'a'],
weight: 7,
something: 'ththh'
},
{
tags: ['a', 'c', 'g', 'e'],
weight: 5,
something: 'ghjghj'
}
];
const finalTags = [];
const finalWeight = [];
// TODO: find a better way to do this
arr.forEach(v => {
if (finalWeight.indexOf(v.weight) === -1) finalWeight.push(v.weight);
v.tags.forEach(val => {
if (finalTags.indexOf(val) === -1) finalTags.push(val);
});
});
// Ascending order
finalTags.sort();
finalWeight.sort();
what i have above works, but seems a bit messy and was wandering if there was a better/tidier way of doing this
Upvotes: 6
Views: 100
Reputation: 19070
You can use Array.prototype.reduce() combined with Set in order to get an object with the sorted arrays {tags: [], weights: []}
:
const arr = [{tags: ['f', 'b', 'd'],weight: 7,something: 'sdfsdf'},{tags: ['a', 'b', 'c', 'd', 'e'],weight: 6,something: 'frddd'},{tags: ['f', 'c', 'e', 'a'],weight: 7,something: 'ththh'},{tags: ['a', 'c', 'g', 'e'],weight: 5,something: 'ghjghj'}];
const obj = arr.reduce((a, {tags, weight}) => {
a.tags = [...new Set(a.tags.concat(tags))];
a.weights = [...new Set(a.weights.concat(weight))];
return a;
}, {tags: [], weights: []});
// final result i want
console.log('finalTags:', obj.tags.sort()); // ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
console.log('finalWeight:', obj.weights.sort()); // [5, 6, 7];
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 3512
You could use the following code. This basically splits arr
up into finalTags
and finalWeights
.
.flat()
flattens the array ([1, [2, [3]]]
would become [1, 2, 3]
)
finalTags.filter((item, index) => finalTags.indexOf(item) >= index).sort();
remove's the duplicates.
const arr = [{
tags: ['f', 'b', 'd'],
weight: 7,
something: 'sdfsdf'
},
{
tags: ['a', 'b', 'c', 'd', 'e'],
weight: 6,
something: 'frddd'
},
{
tags: ['f', 'c', 'e', 'a'],
weight: 7,
something: 'ththh'
},
{
tags: ['a', 'c', 'g', 'e'],
weight: 5,
something: 'ghjghj'
}
];
let finalTags = arr.map(e => e.tags);
finalTags = finalTags.flat();
finalTags = finalTags.filter((item, index) => finalTags.indexOf(item) >= index).sort();
let finalWeight = arr.map(e => e.weight);
finalWeight = finalWeight.filter((item, index) => finalWeight.indexOf(item) >= index).sort();
console.log(finalTags);
console.log(finalWeight);
Sources:
Removing duplicates: https://gomakethings.com/removing-duplicates-from-an-array-with-vanilla-javascript/
Upvotes: 0
Reputation: 17190
One solution is to use Array.reduce() to create two sets, one with the tags
and other with the weights
. After this you can transform the sets
to arrays
and use Array.sort() on they:
const arr = [
{
tags: ['f', 'b', 'd'],
weight: 7,
something: 'sdfsdf'
},
{
tags: ['a', 'b', 'c', 'd', 'e'],
weight: 6,
something: 'frddd'
},
{
tags: ['f', 'c', 'e', 'a'],
weight: 7,
something: 'ththh'
},
{
tags: ['a', 'c', 'g', 'e'],
weight: 5,
something: 'ghjghj'
}
];
let res = arr.reduce((acc, {tags, weight}) =>
{
acc.tags = new Set([...acc.tags, ...tags]);
acc.weights.add(weight);
return acc;
}, {tags: new Set(), weights: new Set()});
let sortedWeigths = [...res.weights].sort();
let sortedTags = [...res.tags].sort((a, b) => a.localeCompare(b));
console.log("weights: ", sortedWeigths, "tags: ", sortedTags);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Upvotes: 2