【问题标题】:How to Destructure JSON array>object>array如何解构 JSON 数组>对象>数组
【发布时间】:2022-10-23 22:40:33
【问题描述】:

我正在尝试解构一个如下所示的 JSON 文件:

[
  {
    "Bags": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  },
  {
    "Shoes": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  }
]

这样我就得到了对象的名称(“包”和“鞋”)。

我正在尝试在页面上打印结果,基于 which is which 我将名称作为字符串提供给 Store 组件,如下所示:

<Route path="/store" element={<Store merch="Bags" />} />

这是我的 Store.tsx 文件,它根本不起作用,但这是我的尝试:

import storeItems from "../data/items.json";
import { Row, Col, Container } from "react-bootstrap";
import { StoreItem } from "../components/StoreItem";
import { useState } from "react";

type StoreProps = {
  merch: string;
};

export function Store({ merch }: StoreProps) {
  const [data, setData] = useState([]);
  for (let i = 0; i < storeItems.length; i++) {
    let a = Object.values(storeItems[i]);
    console.log(a);
  }
  console.log(storeItems);
  return (
    <>
      <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
        <h1 className="m-5">Bags</h1>
        <Row md={2} xs={1} lg={3} className="g-3">
          {storeItems.map((item) => (
            <Col>
              <StoreItem key={item.id} {...item} />
            </Col>
          ))}
        </Row>
      </Container>
    </>
  );
}

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    为了从您的storeItems 获得["Bags", "Shoes"],您可以:

    const names = storeItems.flatMap(mi => Object.keys(mi));
    

    这也会在同一个对象上获得额外的键,所以如果你有:

    const storeItems = [
        { "Bags": /*...*/{}, "Bags2": /*...*/{}, },
        { "Shoes": /*...*/{} },
    ];
    

    那么它将返回[ "Bags", "Bags2", "Shoes" ]

    我不得不说,你的数据格式很奇怪,但我完全按照书面回答了这个问题

    此外,如果您想要列表中所有对象的names,例如每个对象的name 属性,您可以执行以下操作:

    const names = storeItems.flatMap(storeItem =>
        Object
            .values(storeItem)
            .flatMap(itemList => itemList.map(item => item.name))
    );
    

    此外,如果您想要一个对象的键中所有对象的 names 名称(如“包”或“鞋”),那么您可以:

    const names = Object.fromEntries(storeItems.flatMap(storeItem => 
        Object.entries(storeItem)
    ).map([k,v] => [k,v.map(i => i.name)]))
    

    我不太确定你想要哪一个,所以我把它们都包括了(:

    编辑

    查看您的代码,您似乎想要获取数据的特定部分。这可以通过以下方式完成:

    const name = "Shoes";
    const items = storeItems.flatMap(si => Object.entries(si))[name]
    

    或者如果你知道你的数据总是先有鞋子并且格式准确,那么你可以这样做

    const name = "Shoes";
    const items = storeItems[1]["Shoes"];
    

    【讨论】:

    • 非常翔实和详细的答案,谢谢!
    • 但是现在想想,可能是我的json数据有问题。我只想要一组命名的数组。也许我的数据格式是错误的。我希望能够在 sortItems 数组中搜索特定关键字并显示该关键字数组中的所有项目。
    【解决方案2】:

    这是你想要做的吗?

    const products = [
      {
        "Bags": [
          {
            "id": 1,
            "name": "Michael Kors Bag",
            "price": 235,
            "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
          },
          {
            "id": 2,
            "name": "Ted Baker Bag",
            "price": 495,
            "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
          },
          {
            "id": 3,
            "name": "Coach Bag",
            "price": 238,
            "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
          },
          {
            "id": 4,
            "name": "Kate Spade Bag",
            "price": 35,
            "imgURL": "/imgs/10.jpg"
          }
        ]
      },
      {
        "Shoes": [
          {
            "id": 1,
            "name": "Michael Kors Bag",
            "price": 235,
            "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
          },
          {
            "id": 2,
            "name": "Ted Baker Bag",
            "price": 495,
            "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
          },
          {
            "id": 3,
            "name": "Coach Bag",
            "price": 238,
            "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
          },
          {
            "id": 4,
            "name": "Kate Spade Bag",
            "price": 35,
            "imgURL": "/imgs/10.jpg"
          }
        ]
      }
    ]
    
    const getProductsByKey = key => products
        .filter(product => product.hasOwnProperty([key]))
        .flatMap(obj => obj[key])
    
    console.log(getProductsByKey('Shoes'))
    

    上述代码的输出将是:

    [
      {
        id: 1,
        name: 'Michael Kors Bag',
        price: 235,
        imgURL: '/imgs/03045643da82a42a4a5c86842f4b17f1.jpg'
      },
      {
        id: 2,
        name: 'Ted Baker Bag',
        price: 495,
        imgURL: '/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg'
      },
      {
        id: 3,
        name: 'Coach Bag',
        price: 238,
        imgURL: '/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg'
      },
      { id: 4, name: 'Kate Spade Bag', price: 35, imgURL: '/imgs/10.jpg' }
    ]
    

    请注意,提供的数据不正确,因为“鞋子”项下的项目显然是包。

    我将解释我的代码的原因和方式。首先,我想创建一个可以将任何键作为参数的函数。今天我们有'Bags''Shoes',但明天我们可能会有更多的密钥。因此,我不想提出一个涉及“硬编码”密钥的解决方案。

    一旦我们有了密钥,我们就可以使用Array.prototype.filter 来查找包含我们想要的项目的对象。在我们提供的数据中,'Bags''Shoes' 是键,而不是值。因此我在callbackFn 中使用了product.hasOwnProperty([key])。请注意方括号的使用,因为我们正在搜索名为 key 的动态变量的值,而不是实际的字符串“key”。接下来我们使用Array.protoype.flatMap 来获取我们想要的每个对象的部分,即项目数组。我们在这里使用 .flapMap 来避免嵌套数组,这通常会通过链接过滤器和映射到数据而产生。

    【讨论】:

    • 使用Object.hasOwnProperty 是一种非常聪明的方法!我会使用flatMapObject.entries
    • @Zachiah .flatMap() 是个好主意。我将更新我的答案以包括在内。谢谢你提醒我这件事!
    • 描述您的答案如何以及为什么有效,否则它对网站的未来访问者没有用处。
    【解决方案3】:

    要获取shoes,您可以使用以下命令:

    storeItems[1]["shoes"]
    

    要获得bags,您可以使用以下命令:

    storeItems[0]["bags"]
    

    因此,在您的尝试代码中的 return 表达式中,而不是这样:

    return (
    <>
      <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
        <h1 className="m-5">Bags</h1>
        <Row md={2} xs={1} lg={3} className="g-3">
          {storeItems.map((item) => (
            <Col>
              <StoreItem key={item.id} {...item} />
            </Col>
          ))}
        </Row>
      </Container>
    </>);
    

    使用这个(对于bags):

    return (
    <>
      <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
        <h1 className="m-5">Bags</h1>
        <Row md={2} xs={1} lg={3} className="g-3">
          {storeItems[0]["bags"].map((item) => (
            <Col>
              <StoreItem key={item.id} {...item} />
            </Col>
          ))}
        </Row>
      </Container>
    </>);
    

    【讨论】:

    • 我将如何遍历每个数组项?我不想硬编码“包”和“鞋”这两个词。
    • 如果您不想在代码中使用硬编码字符串,我认为使用 .flatMap 可以解决它。
    【解决方案4】:

    const storeItems = [
      {
        "Bags": [
          {
            "id": 1,
            "name": "Michael Kors Bag",
            "price": 235,
            "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
          },
          {
            "id": 2,
            "name": "Ted Baker Bag",
            "price": 495,
            "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
          },
          {
            "id": 3,
            "name": "Coach Bag",
            "price": 238,
            "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
          },
          {
            "id": 4,
            "name": "Kate Spade Bag",
            "price": 35,
            "imgURL": "/imgs/10.jpg"
          }
        ]
      },
      {
        "Shoes": [
          {
            "id": 1,
            "name": "Michael Kors Bag",
            "price": 235,
            "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
          },
          {
            "id": 2,
            "name": "Ted Baker Bag",
            "price": 495,
            "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
          },
          {
            "id": 3,
            "name": "Coach Bag",
            "price": 238,
            "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
          },
          {
            "id": 4,
            "name": "Kate Spade Bag",
            "price": 35,
            "imgURL": "/imgs/10.jpg"
          }
        ]
      }
    ]
    
    
    // Get the values for merch types
    const categories = storeItems.map((entry) => Object.keys(entry)[0])
    console.log(categories)
    
    // Find the products for a given merch
    const merch = 'Shoes'
    const products = storeItems.find((entry) => entry[merch])[merch]
    console.log(products)

    【讨论】:

    • 等这个成功了,谢谢!
    • 没有任何解释的答案不是很有用。
    猜你喜欢
    • 2019-12-01
    • 2011-02-05
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 2018-11-13
    • 2015-05-22
    • 1970-01-01
    相关资源
    最近更新 更多