【问题标题】:Modify object while passing through react component在通过反应组件时修改对象
【发布时间】:2019-10-20 06:18:44
【问题描述】:

我试图通过一个看起来像这样的对象

{ 
    "nodes": [
            {
              "attributes": null
            },
            {
              "attributes": {
                "nodes": [
                  {
                    "attributeId": 1,
                    "name": "pa_color",
                    "options": [
                      "gray"
                    ]
                  },
                  {
                    "attributeId": 2,
                    "name": "pa_size",
                    "options": [
                      "large"
                    ]
                  }
                ]
              }
            },
            {
              "attributes": {
                "nodes": [
                  {
                    "attributeId": 1,
                    "name": "pa_color",
                    "options": [
                      "blue"
                    ]
                  }
                ]
              }
            }
          ]
}

到一个反应组件中,该组件以所有唯一名称呈现所有不同的选项。但是,数据的结构方式意味着我会收到重复的名称和选项。

我正在尝试将对象转换为这个对象

{ 
    "node": {
        "attributeId": 1,
        "name": "pa_color",
        "values": [
          {
            "name": "gray"
          },
          {
            "name": "blue"
          }
        ]
    },
    "node": {
        "attributeId": 2,
        "name": "pa_size",
        "values": [
          {
            "name": "large"
          }
        ]
    },
}

当前代码如下所示

export interface Category_products_edges_node_attributes_edges_node {
  __typename: "ProductAttribute";
  /**
   * Attribute Global ID
   */
  name: string;
  /**
   * Attribute options
   */
  options: (string | null)[] | null;
  /**
   * Attribute ID
   */
  attributeId: number;
}

export interface ProductFiltersProps {
  attributes: Category_products_edges_node_attributes_edges_node[]
}

export const ProductFilters: React.FC<ProductFiltersProps> = ({
  attributes,
}) => (
  <div className="product-filters">
    <div className="container">
      <div className="product-filters__grid">
        {attributes.map(attribute => (

我已经尝试过了

{groupBy(attributes, 'attributeId').map(attribute => (

使用 Lodash 库,但收到错误

此表达式不可调用。类型 'Category_products_edges_node_attributes_edges_node[]' 没有调用 签名。

最好的方法是什么?

谢谢

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    lodash groupBy 返回Object 而不是Array,因此javascript .map 调用将无法处理它。 groupBy 还用于将具有相似属性的项目分组到对象内的一个键下,它不用于删除重复项。

    要删除重复项,请使用lodash uniqBy 方法。该方法可以在数组上调用,返回一个不重复的数组。

    更新: 要更详细地查看如何根据对象的多个属性删除重复项,请参阅出色的answer

    您尝试实现的输出对象也具有相似的键,我认为这不是您想要的,Javascript 对象不应该有重复的键。所以我的输出将键作为node0, node1 而不是node

    您可以通过以下方式实现:

    const nodes = {
    	nodes: [
    		{ attributes: null },
    		{
    			attributes: {
    				nodes: [
    					{ attributeId: 1, name: "pa_color", options: ["gray"] },
    					{ attributeId: 2, name: "pa_size", options: ["large"] }
    				]
    			}
    		},
    		{
    			attributes: {
    				nodes: [{ attributeId: 1, name: "pa_color", options: ["blue"] }]
    			}
    		}
    	]
    }
    
    const attributes = []
    nodes.nodes.forEach(e => {
    	if (e.attributes && Array.isArray(e.attributes.nodes)) {
    		attributes.push(...e.attributes.nodes)
    	}
    })
    
    const uniqueAttributes = _.uniqBy(attributes, (obj) => [obj.attributeId, obj.name, obj.options].join())
    const uniqueNodes = uniqueAttributes.map((e, i) => ({ ["node" + i]: e }))
    
    console.log("Unique Nodes: ", uniqueNodes)
    &lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 我使用了很多 ES6,所以如果你不理解部分语法,请告诉我
    • 感谢您的回答。结果仅返回两个 pa_color 选项中的一个“灰色”。是否可以将 ["attributeId","name","options"] 作为参数传递,而不仅仅是 "attributeId"?
    • 是的,你可以。检查更新的答案我已经链接了另一个答案,该答案非常详细地显示了这一点
    猜你喜欢
    • 2021-09-20
    • 2017-12-30
    • 1970-01-01
    • 2023-03-14
    • 2021-09-28
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 2020-06-02
    相关资源
    最近更新 更多