如何通过删除重复项来映射数组

How to Map array by removing duplicates

我正在使用 React.js 开发一个应用程序并使用 Relay.js 来获取数据,并且对这样的组件有一个 JSON 响应:

{
  outfit(id :"T3V0Zml0Tm9kZTo1") {
    id
    title
    productvariant {
      edges {
        node {
          id
          title
          product {
            edges {
              node {
                id
                brand
              }
            }
          }
        }
      }
    }
  }
}

(github link),我将所有产品映射到一个标签中,如下所示:

<Grid>
  { this.props.outfit.productvariant.edges.map((variantEdge, i) => (
    <Grid.Column mobile={16} tablet={8} computer={12}>
      <Grid.Column mobile={16} tablet={8} computer={12}>
        <article id ={variantEdge.node.id} >
          <header style = {styles.header}>
            <h2>
              {variantEdge.node.title}
            </h2>
          </header>
        </article>
        <Tabs defaultActiveKey={1} id="uncontrolled-tab-example">
          <Tab eventKey={1} title="Tab 1">
            <section style = {styles.row}>
              {variantEdge.node.product.edges.map((productEdge,i) =>(
                <section >
                  <section  >
                    <Card   style = {styles.col23} >
                      <Image src="https://cdn.lookastic.com/beige-dress-shirt/roberto-cavalli-ruffled-cotton-voile-shirt-medium-591164.jpg" />
                        <Card.Content  style = {styles.col23}>
                          <Card.Header>{productEdge.node.title}</Card.Header>
                        </Card.Content>
                      </Card>
                    </section>
                  </section>
                ))}
              </section>

(github link)。正如您在回复中看到的,我有带有 field 品牌的产品。我如何循环品牌并删除重复项并将它们映射到侧边导航?我想在选项卡组件旁边有一个侧边导航小部件,它将显示该特定产品可用的所有品牌。

我假设您想修复上面代码中的现有循环?如果是这样,您可以通过几种方式完成此操作。

方法一:

这是最干净、最易读的版本,但它要求您 运行 在 render() 函数之前和之外编写一些代码。

var mySet = new Set();
this.props.outfit.productvariant.edges.forEach((variantEdge) => {
  variantEdge.node.product.edges.forEach((productEdge) =>
    mySet.add(productEdge.node.brand);  //add each brand to a Set, which guarantees uniqueness
  });
});

然后您可以在 render() 中执行 map()。替换为:

{variantEdge.node.product.edges.map((productEdge,i) =>(

有了这个:

[...mySet].map((productEdge, i) => (

方法二:

这里有一个方便的 one-liner,您可以使用。它的可读性不是很好,但是如果你想要一些紧凑的东西就可以了:

{variantEdge.node.product.edges.filter((productEdge, i, self) => self.findIndex((p) => {return p.node.brand === productEdge.node.brand}) === i.node.brand).map((productEdge, i) => (

以上代码假设存在productEdge.node.brand


我建议使用前一种方法,因为它(可能)性能更好,而且更易于阅读和调试。请注意,由于整个对象的复杂性,我可能遗漏了上面的一些小问题;然而,核心概念应该可以正常工作。

祝你好运。