Array.map/过滤连续数组,然后重新排序使其再次连续



使用React,我有一个列表组件,它使用array.map来呈现项目列表。

清单项目五花八门;每个其他列表项都有不同的背景色,这取决于提供列表项的数据结构的id字段是偶数还是奇数:

...
const useStyles = makeStyles((theme) => ({
even: {
backgroundColor: theme.palette.background.paper,
},
odd: {
backgroundColor: "#c8c9c7",
},
}));
...
const classes = useStyles();
...
{!list || list.length < 1 ? (
<p>You have no assets selected...</p>
) : (
list.map((items) => (
<ListItem
className={items.id % 2 === 0 ? classes.even : classes.odd}
key={items.id}
>
...
/>
</ListItem>
))
)}

以下是它使用的数据结构示例:

{
{
"id":0,
"foo":"This is a bar"
},
{
"id":1,
"foo":"This is also a bar"
},
{
"id":2,
"foo":"Yes, this too, is a bar"
}
}

我需要删除项目。普通的javascript.filter按预期生成不连续的id:

{
{
"id":0,
"foo":"This is a bar"
},
{
"id":2,
"foo":"Yes, this too, is a bar"
}
}

我需要它们是连续的:

{
{
"id":0,
"foo":"This is a bar"
},
{
"id":1,
"foo":"Yes, this too, is a bar"
}
}

我有一个功能可以满足我的需要,需要一些调整:

const handleRemoveAsset = (id) => {
const arrayCopy = [...assetListItems];
const filteredArray = arrayCopy
.filter((item) => item.id !== id)
for (var i=0; i < filteredArray.length; i++) {
filteredArray[i].id = i;
}
setAssetListItems(filteredArray);
};

这是可行的,但不能简单地使用React。。。我希望在整个过程中使用过滤器和/或映射,而不是使用我的for循环。

我读到你可以链接过滤器和地图,并尝试过,但无法完全解决。我想出了这个:

const filteredArray = array
.filter((item) => item.id !== id)
.map((item, index) => {
item && item.id ? item.id : index)});

它无法用-编译,期望对函数调用进行赋值,而是在.map.之后的行上看到了一个表达式

在这一点上,任何建议都将不胜感激,谢谢!

您可以链接mapfilter,并从map返回新对象,该对象将更新预先存在的id。

[...assetListItems]
.filter(item => item.id !== id)
.map((item, index) => ({
...item,
id: index,
}));

我刚刚考虑了另一种情况,如果id不是以0开始的。如果您希望resultant array中的起始id作为第一个对象的id,那么这只是实现预期输出的另一种方式。

let data = [{id:0, foo:'This is a bar'},{id:1, foo:'This is also a bar'},{id:2, foo:'Yes, this too, is a bar'}];

const filterItems = (items, id) => {
let lastPushedId = items[0]?.id;
return items.filter(item => item.id !== id).map(item => ({
...item,
id: lastPushedId++
}))
}
console.log(filterItems(data, 1));
//`id` of the first object is `3`
data = [{id:3, foo:'This is a bar'},{id:4, foo:'This is also a bar'},{id:5, foo:'Yes, this too, is a bar'}];
console.log(filterItems(data, 3));
.as-console-wrapper {
max-height: 100% !important;
}

最新更新