Reputation: 53
I am outputting the matched value of projects
when the name of my logo
matches the items
object within projects
with the help of a reduce
function. However, whenever I click on multiple logos that both match project.items
I am rendering duplicates.
Here is my code:
logos.reduce((acc, logo) => {
if (logo.active) {
Object.values(projects).forEach((proj) => {
if (Object.values(proj.items).includes(logo.name)) {
console.log(acc)
acc.push((<Project title={proj.title} routeName={proj.routeName} items={proj.items} description={proj.description}/>));
}
});
}
return acc
}, [])
My first idea was to create another array, run a for loop and iterate through the values like: filteredValues[i].props.title
and push the contents of that loop to an array. I ran run a reduce
on that array like this but I was not able to eliminate the duplicate:
const filteredArr = arr.reduce((acc, current) => {
const x = acc.find(item => item.title === current.title);
if (!x) {
return acc.concat([current]);
} else {
return acc;
}
}, []);
Anyway, here's the output of acc
which I am using to render my Project
component
Upvotes: 0
Views: 1367
Reputation: 53
I had to run a reduce
function outside of the original forEach
loop and check those values with a some
function.
logos.reduce((acc, logo) => {
if (logo.active) {
Object.values(projects).forEach((proj) => {
if (Object.values(proj.items).includes(logo.name)) {
console.log(acc)
acc.push((<Project title={proj.title} routeName={proj.routeName} items={proj.items} description={proj.description}/>));
}
});
acc = acc.reduce(function (p, c) {
if (!p.some(function (el) { return el.props.title === c.props.title; })) p.push(c);
return p;
}, []);
}
return acc
}, [])
Upvotes: 0
Reputation: 499
May be below code is what you need.
const filteredArr = this.getUnique(arr, 'title');
getUnique(arr, comp) {
const unique = arr.map(e => e[comp]).map((e, i, final) => final.indexOf(e) === i && i).filter((e) => arr[e]).map(e => arr[e]);
return unique;
}
Steps involve is to:
Upvotes: 2
Reputation: 7096
You can use the Map object to filter out duplicates.
let arrFiltered = [];
// form map of unique arr items
const arrMap = new Map();
arr.forEach(item => arrMap.set(item.title, item));
// form array of all items in map
arrMap.forEach(item => arrFiltered.push(item));
Upvotes: 0
Reputation: 679
You can write your original loop like this
logos
.reduce((acc, logo) => {
if (logo.active) {
Object.values(projects).forEach((proj) => {
if (
Object.values(proj.items).includes(logo.name) &&
!acc.find((item) => item.value === logo.name)
) {
console.log(acc);
acc.push({
value: logo.name,
component: (
<Project
title={proj.title}
routeName={proj.routeName}
items={proj.items}
description={proj.description}
/>
),
});
}
});
}
return acc;
}, [])
.map((values) => values.component);
Upvotes: 0