如何从唯一且不重复的对象映射项目

Posted

技术标签:

【中文标题】如何从唯一且不重复的对象映射项目【英文标题】:How to map items from an object that are unique and not repeating 【发布时间】:2019-01-17 18:42:07 【问题描述】:

我正在制作一个电子商务反应原生应用程序,并且在应用程序的 CART 部分中,我希望添加到购物车中的具有相同 ID(您可以在控制台中看到的类别 ID)的每个项目只呈现一次,但是在我的情况下,如果我在购物车中添加 3 个具有相同 id 的项目,我将看到 3 个不同的 listItems 他们尊重的项目。如果有多个具有相同 ID 且数量增加的项目,我希望我的地图功能显示 1 个列表项。到目前为止,我的代码只是将每个选定的产品呈现为一个单独的项目:

renderItems() 
let items = [];
this.state.cartItems.map((item, i) => 
  console.log(item)
  items.push(
    <ListItem
      key=i
      last=this.state.cartItems.length === i + 1
      onPress=() => this.itemClicked(item)
    >
      <Thumbnail square style= width: 100, height: 100  source= uri: item.productdetail.image  />
      <Body style= paddingLeft: 10 >
        <Text style= fontSize: 16 >

          item.productdetail.name

        </Text>

        <Text style= fontSize: 14, fontStyle: 'italic' >Price: item.productdetail.price</Text>
        <Text style= fontSize: 14, fontStyle: 'italic' >Quantity: item.quantity > 1 ? item.quantity : 1</Text>

      </Body>
      <Right>
        <Button style= marginLeft: -25  transparent onPress=() => this.removeItemPressed(item)>
          <Icon size=30 style= fontSize: 30, color: '#95a5a6'  name='ios-remove-circle-outline' />
        </Button>
      </Right>
    </ListItem>
  );
);
return items;

console.log的结果如下

这就是我的购物车的样子

现在您可以看到购物车应该只显示一个 listItem 具有相同产品的数量=18

【问题讨论】:

根据id过滤数据,然后使用map遍历内容 【参考方案1】:

考虑到您有一个像这样的简单数据集:

const rawItemsData = [
    id: 1, qty: 2,
    id: 1, qty: 3,
    id: 2, qty: 1,
    id: 1, qty: 2,
    id: 2, qty: 5,
    id: 3, qty: 6
];

如果你想得到一个具有唯一项目 id 和总数量的数组,你可以使用 reduce :

const uniqueItemsData = rawItemsData.reduce((prev, item) => 
    const existingItem = prev.find((id) => id === item.id);
    if(existingItem)
        existingItem.qty = existingItem.qty + item.qty;
    else
        prev.push(item);
   return prev;
 , []); //-> [  id: 1, qty: 7 ,  id: 2, qty: 6 ,  id: 3, qty: 6  ];


 //Then you can use your code : 
 uniqueItemsData.map((item, id) => 
     //..
 );

【讨论】:

在 prev.find((id) => id === item.id); 中,我会在 'id' 中得到什么? 这一行正在使用对象解构。 find 将遍历现有项目并执行回调。在此回调中,变量id 将保存当前项目id 属性的值 简单来说,你也可以写成:prev.find((testItem) =&gt; testItem.id === item.id); 您编辑了我的答案,这降低了它的可读性,所以我拒绝了编辑。但是,是的,我认为你说得对 我遇到类型错误:'' undefined is not an object (testItem.productDetail)"【参考方案2】:

在这种情况下,您必须在推送之前进行简单的控制,无论该项目是否存在。由您来设计:

例如,您可以创建另一个包含唯一项目的列表。在这样的页面中,我相信保存独特的项目很有用,您可能在其他地方也需要相关信息。而且这个列表不应该需要 setState,因为它只是用于控件。

this.state.uniqueItems = [];

在每次推送中,将项目添加到 uniqueItems。此处不要使用 setState 会造成冗余渲染:

this.state.uniqueItems.push(item);

在map函数中,在push之前,检查它的id是否存在于唯一列表中。您可以在这里使用简单的 for 循环、lodash 库或 Array 的 find 方法。

【讨论】:

以上是关于如何从唯一且不重复的对象映射项目的主要内容,如果未能解决你的问题,请参考以下文章

JS如何从数组中随机取出若干个数,且不重复

js如何从一个数组中随机取出n个不同且不重复的值

js如何从一个数组中随机取出n个不同且不重复的值

如何从特定索引映射然后在特定索引之后停止[重复]

如何使用Javascript从特定的单个数组中查找所有不重复的组合

在c#中随机抽取数据库中数据且不重复怎么实现SQL语句