Как визуализировать и элемент один раз в функции карты? У меня есть и массив объектов, и я хочу отобразить значение цвета только один раз в другой компонент, я попытался вставить цвет в массив и проверить его, но поскольку он находится внутри цикла, он добавляется мгновенно, и эта проверка потерпит неудачу, дело в том, что я не хочу, чтобы один и тот же цвет отображался дважды, если он найден, то только один раз… есть ли хорошее решение для этого случая?
const items =[{car : 'bmw', color : 'black'}, {car: 'opel', color :'black'}, {car:'landrover',color:'red'}]
{items.map((item, i) => {
let arr = [];
//arr.push(items[i].color);
return (
<React.Fragment>
{arr.includes(items[i]) ? undefined : <colors img={items[i]?.color} /> }
<items key={item.id} Car={item.car} />
</React.Fragment>
);
})}
// Expected result
// black color component
// 'bmw'
// 'opel'
// red color component
// 'landrover'
4 ответа
Я предлагаю вам сначала отсортировать элементы по цвету, а затем визуализировать цветовой компонент только тогда, когда цвет отличается от предыдущего элемента:
items
.sort((a, b) => a.color.localeCompare(b.color))
.map((item, index, sortedItems) => {
const colorChanged = !index || item.color !== sortedItems[index - 1].color
return (
<>
{ colorChanged && <colors img={items[i]?.color} /> }
<items key={item.id} Car={item.car} />
</>
)
})
Редактировать: поскольку index
является целым числом >= 0, !index
будет оцениваться как true точно тогда, когда это делает index === 0
.
const itemColors = items
.map(({ color }) => color) // create array of colors
.filter((value, index, self) => self.indexOf(value) === index) // remove duplicates
// do your rendering here
Или с помощью lodash
color
. В этом случае вы либо пишете функцию groupBy
самостоятельно, либо находите ее в служебной библиотеке, такой как lodash
, которая имеет groupBy
const items =[
{car : 'bmw', color : 'black'},
{car: 'opel', color :'black'},
{car:'landrover',color:'red'}
]
//Expected Outcome
/*
[
{
color: 'black'
cars: ['bmw','opel']
},
{
color: 'black'
cars: ['bmw','opel']
}
]
*/
const finalResult = items.reduce((acc, cur, arr) => {
let res = [...acc];
const matchIndex = res.findIndex(obj => obj.color === cur.color);
if (matchIndex === -1) {
res.push({
color: cur.color,
cars: [cur.car]
})
} else {
res[matchIndex].cars.push(cur.car)
}
acc = res;
return acc;
}, []
)
console.log(finalResult);
finalResult.forEach(colorObject => {
colorObject.cars.forEach(car => {
console.log(
`Your Component with Color ${colorObject.color} and Car ${car}`
);
})
})
Поэтому вам нужно будет сначала отфильтровать значение цвета и создать массив без повторяющихся цветов. Затем вам нужно отобразить название автомобиля, отфильтровав его по цвету. Простой подход без какой-либо сторонней библиотеки будет таким:
const colors = items
.map((data) => data.color)
.filter((v, i, s) => s.indexOf(v) === i)
{colors.map((color) => (
<div>
{color}
{items.filter(item => item.color === color).map((item)=> (
<>{item.car}</>
)}
</div>
)}
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.