Как сопоставить массив объектов, в котором также есть массив объектов?

Я использую TypeScript, и я немного новичок в этом. У меня есть такой массив, но ключи в 'orderBreakdownList' ("8" и "восходящий тренд") будут неизвестны приложению каждый раз, когда оно загружается.

{
  "userId": "00bdad66",
  "totalNumberOfOrders": 5,
  "totalNumberOfPackages": 54521,
  "totalNumberOfItems": 13,
  "totalNumberOfDeliveredOrders": 3,
  "totalPrice": 39409.0,
  "orderBreakdownList": [
    {
      "8": {
        "noOfItems": 1,
        "noOfPackages": 17160,
        "id": 8,
        "totalPrice": 3741.52,
        "orderItems": [
          {
            "upward-trending": {
              "tag": "upward-trending",
              "value": 6653.16,
              "price": 18798.89,
              "id": 76
            }
          }
        ]
      }
    }
  ]
}

Я пытаюсь отобразить массив orderBreakdownList, внутри которого есть объекты, и отобразить второй массив в список. (Выпадающая таблица с данными по одному элементу)

это то, что я пробовал до сих пор,

<div>
      {orderBreakdownList.map((items, index) => {
        return (
          <ol key = {index}>
            {items.map((subItems, sIndex) => {
              return <li key = {sIndex}> {subItems} </li>;
            })}
          </ol>
        );
     })}
</div>

Но я не заставляю это работать и не получаю никаких данных. Может быть, мне нужна другая карта в него? Мне нужна помощь, пожалуйста.

Обновлено: По предложению @rantao я придумал следующий код. Использование только html без рамки CSS.

<div>
      {orderBreakdownList.map((orderBreakdown, i) => {
        const keyName = Object.keys(orderBreakdown);
        return (
          <div key = {i}>
            Order number: {keyName}
            {Object.values(orderBreakdown).map(
              (
                { noOfItems, noOfPackages, id, totalPrice, orderItems }: any,
                i
              ) => {
                return (
                  <div key = {i}>
                    <div>Id: {id}</div>
                    <div>Nr. of items: {noOfItems}</div>
                    <div>Nr. of packages: {noOfPackages}</div>
                    <div>Total price:{totalPrice}</div>
                    <ul>
                      {orderItems.map((item: any) =>
                        Object.values(item).map(
                          ({ tag, value, price, id }: any) => (
                            <li key = {id}>
                              <div>Id: {id}</div>
                              <div>Tag: {tag}</div>
                              <div>Value: {value}</div>
                              <div>Price: {price}</div>
                            </li>
                          )
                        )
                      )}
                    </ul>
                  </div>
                );
              }
            )}
          </div>
        );
      })}
    </div>
items не является массивом, поэтому вы не можете его сопоставить. items (лучше называть item) — это отдельный элемент в массиве orderBreakdownList. Отдельный элемент, который я вижу, имеет одно свойство 8 с объектом в качестве значения, и этот объект имеет свойство orderItems. Так что вам нужно вместо items.map, items.8.orderItems.map. Не уверен, что это за 8, похоже на запах кода.
James 04.10.2022 20:39

Вы не можете отображать items как объект.

IAmRC1 04.10.2022 20:40

@James OP сказал, что 8 и upward-trending будут неизвестны, поэтому вы не можете явно сделать items.8.orderItems, потому что ключ неизвестен. Смотрите мой ответ, в котором используются Object.values и Object.entries, чтобы смягчить это ограничение.

rantao 04.10.2022 21:01

@rantao, конечно, пункт был «не сопоставлять элементы, это не массив»

James 04.10.2022 21:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

items — это объект, и вы можете получить подэлементы, получив ключи объекта. Затем вы можете улучшить это оттуда

<div>
      {orderBreakdownList.map((items, index) => {
       let keyName = Object.keys(items);
        return (
          <ol key = {index}>
              <li> {items[keyName]} </li>;
          </ol>
        );
     })}
</div>
Ответ принят как подходящий

Я предполагаю, что когда вы говорите «второй массив», вы имеете в виду orderItems внутри массива orderBreakdownList. В этом случае вы бы сделали что-то вроде этого:

<div>
  {orderBreakdownList.map(orderBreakdown => (
    <ol>
      {Object.values(orderBreakdown).map(({ orderItems }) => (
        orderItems.map(item => (
          Object.values(item).map(({ tag, value, price, id }) => (
            <li key = {id}>
              <div>{tag}</div>
              <div>{value}</div>
              <div>{price}</div>
            </li>
          )) 
        ))
      ))}
    </ol>
  ))}
</div>

Object.values() принимает значения объекта без явного определения ключей — 8 и upward-trending в данном случае. Если вы хотите узнать, что такое ключ, замените Object.values() на Object.entries(), который возвращает массив кортежей, содержащих key и value объекта.

Например:

Object.entries(item).map(([key, value]) => {
 // Map nested item
})

Спасибо за ваш очень подробный и четкий ответ, много "приятностей". Я нахожу массивы забавными, но сложными. Что, если я хочу отобразить как значение ключей, так и объекты? Должен ли я запускать Object.value() в родительском массиве? (В данном случае цифра 8)

Christer Johansson 04.10.2022 21:22

Без проблем! В этом случае используйте Object.entries вместо Object.values. Пример уже есть в моем ответе

rantao 04.10.2022 21:24

Другие вопросы по теме