Как выполнить итерацию по словарю вложенных массивов в файле json с помощью ванильного javascript?

#javascript #html #json

Вопрос:

script.js

 fetch("pizzas.json").then((response) =>
  response.json().then((data) => {
    let jsonSize = data.length;

    let htmlContent = "";
    for (let i = 0; i < jsonSize; i  ) {
      let id = data[i].id;
      let name = data[i].name;
      let img = data[i].img;
      let price = data[i].price;
      let sizes = data[i].sizes;
      let description = data[i].description;
      let cheese = data[i].cheese;
      console.log(i);
      htmlContent  = `
           <div class="column-pizza">
            <a href="">
              <div class="pizza-item--img">
                <img src="${img}" id="pizza-img-${i}" />
              </div>
              <div class="pizza-item--add" id="selected-${i}">Add</div>
            </a>
            <div class="pizza-item--price" id="pizza-price-${i}">₹${price}</div>
            <div class="pizza-item--name" id="pizza-name-${i}">${name}</div>
            <div class="pizza-item--desc" id="pizza-desc-${i}">${description}</div>
            <div class="pizza-item--sizes" id="pizza-size-${i}">
                <input
                  type="radio"
                  id="small-1"
                  name="sizes-1"
                  value="small"
                />
                <label for="small">${sizes[i]}</label>
                <input
                  type="radio"
                  id="medium-1"
                  name="sizes-1"
                  value="medium"
                />
                <label for="medium">${sizes[i   1]}</label>
                <input
                  type="radio"
                  id="large-1"
                  name="sizes-1"
                  value="large"
                />
                <label for="large">${sizes[i   2]}</label>
              </div>
        </div>`;
     }
    document.querySelector("#root").innerHTML = htmlContent;
  })
);
 

пицца.json

 [
  {
    "id": 1,
    "name": "Tandoori Paneer",
    "img": "/images/pizza.png",
    "price": 200,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Spiced paneer, Onion, Green Capsicum amp; Red Paprika in Tandoori Sauce",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  },
  {
    "id": 2,
    "name": "Veggie Supreme",
    "img": "images/pizza.png",
    "price": 250,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Black Olives, Green Capsicum, Mushroom, Onion, Red Paprika, Sweet Corn",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  },
  {
    "id": 3,
    "name": "Veg Exotica",
    "img": "images/pizza.png",
    "price": 300,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Baby Corn, Black Olives, Green Capsicum, Jalapeno, Red Capsicum",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  }
]
 

МОИ СОМНЕНИЯ:

  1. Как получить доступ к массиву объектов размера в pizzas.json и использовать его в script.js
  2. Кроме того, когда я использую ${size[i]} , ${size[i 1]} , ${size[i 2]} , он не показывает правильный вывод, так как , когда я становлюсь больше 0, он ссылается size[1] , size[2] и size[3] где size[3] его нет.МОЕ МНЕНИЕ О:
    Для проблемы индексирования размера [] могу ли я использовать код javascript между htmlContent?
    Пожалуйста, помогите.

Ответ №1:

Вы не можете получить доступ к размерам с индексом родительского цикла. Он должен использовать свой собственный цикл. Если данные постоянны, то вы можете сделать что-то подобное для их достижения.

 const data = [
  {
    "id": 1,
    "name": "Tandoori Paneer",
    "img": "/images/pizza.png",
    "price": 200,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Spiced paneer, Onion, Green Capsicum amp; Red Paprika in Tandoori Sauce",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  },
  {
    "id": 2,
    "name": "Veggie Supreme",
    "img": "images/pizza.png",
    "price": 250,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Black Olives, Green Capsicum, Mushroom, Onion, Red Paprika, Sweet Corn",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  },
  {
    "id": 3,
    "name": "Veg Exotica",
    "img": "images/pizza.png",
    "price": 300,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Baby Corn, Black Olives, Green Capsicum, Jalapeno, Red Capsicum",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  }
];

let jsonSize = data.length;

let htmlContent = "";
for (let i = 0; i < jsonSize; i  ) {
  let id = data[i].id;
  let name = data[i].name;
  let img = data[i].img;
  let price = data[i].price;
  let sizes = data[i].sizes;
  let description = data[i].description;
  let cheese = data[i].cheese;
  htmlContent  = `
       <div class="column-pizza">
        <a href="">
          <div class="pizza-item--img">
            <img src="${img}" id="pizza-img-${i}" />
          </div>
          <div class="pizza-item--add" id="selected-${i}">Add</div>
        </a>
        <div class="pizza-item--price" id="pizza-price-${i}">₹${price}</div>
        <div class="pizza-item--name" id="pizza-name-${i}">${name}</div>
        <div class="pizza-item--desc" id="pizza-desc-${i}">${description}</div>
        <div class="pizza-item--sizes" id="pizza-size-${i}">
            <input
              type="radio"
              id="small-1"
              name="sizes-1"
              value="small"
            />
            <label for="small">${sizes[0].Small}</label>
            <input
              type="radio"
              id="medium-1"
              name="sizes-1"
              value="medium"
            />
            <label for="medium">${sizes[1].Medium}</label>
            <input
              type="radio"
              id="large-1"
              name="sizes-1"
              value="large"
            />
            <label for="large">${sizes[2].Large}</label>
          </div>
    </div>`;
 }
document.querySelector("#root").innerHTML = htmlContent; 
 <div id="root"></div> 

И если вы хотите отобразить имя в переключателе, то вы можете сделать вот так.

 const data = [
  {
    "id": 1,
    "name": "Tandoori Paneer",
    "img": "/images/pizza.png",
    "price": 200,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Spiced paneer, Onion, Green Capsicum amp; Red Paprika in Tandoori Sauce",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  },
  {
    "id": 2,
    "name": "Veggie Supreme",
    "img": "images/pizza.png",
    "price": 250,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Black Olives, Green Capsicum, Mushroom, Onion, Red Paprika, Sweet Corn",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  },
  {
    "id": 3,
    "name": "Veg Exotica",
    "img": "images/pizza.png",
    "price": 300,
    "sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }],
    "description": "Baby Corn, Black Olives, Green Capsicum, Jalapeno, Red Capsicum",
    "cheese": [{ "Regular": 0 }, { "Extra Cheese": 100 }, { "No Cheese": 0 }]
  }
];

let jsonSize = data.length;

let htmlContent = "";
for (let i = 0; i < jsonSize; i  ) {
  let id = data[i].id;
  let name = data[i].name;
  let img = data[i].img;
  let price = data[i].price;
  let sizes = data[i].sizes;
  let description = data[i].description;
  let cheese = data[i].cheese;
  htmlContent  = `
       <div class="column-pizza">
        <a href="">
          <div class="pizza-item--img">
            <img src="${img}" id="pizza-img-${i}" />
          </div>
          <div class="pizza-item--add" id="selected-${i}">Add</div>
        </a>
        <div class="pizza-item--price" id="pizza-price-${i}">₹${price}</div>
        <div class="pizza-item--name" id="pizza-name-${i}">${name}</div>
        <div class="pizza-item--desc" id="pizza-desc-${i}">${description}</div>
        <div class="pizza-item--sizes" id="pizza-size-${i}">
            <input
              type="radio"
              id="small-1"
              name="sizes-1"
              value="small"
            />
            <label for="small">${Object.keys(sizes[0])[0]}</label>
            <input
              type="radio"
              id="medium-1"
              name="sizes-1"
              value="medium"
            />
            <label for="medium">${Object.keys(sizes[1])[0]}</label>
            <input
              type="radio"
              id="large-1"
              name="sizes-1"
              value="large"
            />
            <label for="large">${Object.keys(sizes[2])[0]}</label>
          </div>
    </div>`;
 }
document.querySelector("#root").innerHTML = htmlContent; 
 <div id="root" /> 

Ответ №2:

Вы не можете использовать индекс i , так как он представляет объект в pizza массиве. Это нормально index === 0 , но когда индекс превысит 0 , он получит доступ к элементам массива размеров, выходящим за пределы его длины.

Пусть говорят i 1 , что тогда

  • я —> 1
  • i 1 —> 2
  • i 1 —> 3

и sizes в массиве нет ни одного элемента с индексом 3 . Он имеет только индекс до 2(на основе нуля)

"sizes": [{ "Small": 0 }, { "Medium": 100 }, { "Large": 200 }]

Вам нужно взять другую переменную индекса, скажем j , и увеличить ее.

 let j = 0;

.
.
.

<div class="pizza-item--sizes" id="pizza-size-${i}">
                <input
                  type="radio"
                  id="small-1"
                  name="sizes-1"
                  value="small"
                />
                <label for="small">${sizes[j]}</label>
                <input
                  type="radio"
                  id="medium-1"
                  name="sizes-1"
                  value="medium"
                />
                <label for="medium">${sizes[j   1]}</label>
                <input
                  type="radio"
                  id="large-1"
                  name="sizes-1"
                  value="large"
                />
                <label for="large">${sizes[j   2]}</label>
              </div>
 

Если вы хотите получить доступ к property массиву и его value в sizes , то лучше не кодировать его жестко и использовать следующим образом(внимание: выберите только первое свойство). Это сработает, если вы измените size имя, например larget extraLarge .

 const sizes = [{ Small: 0 }, { Medium: 100 }, { Large: 200 }];

// Object.keys - returns the keys from the respective object
for (let j = 0; j < sizes.length;   j) {
  console.log(
    `${Object.keys(sizes[j])[0]} - ${sizes[j][Object.keys(sizes[j])[0]]}`
  );
} 

Ответ №3:

Источник вашей проблемы:


Расширенный размер массива не должен содержать никаких значений и не должен существовать в javascript. Javascript позволяет вам получить доступ к любому индексу, даже если он не существует. См. Следующий пример.

 let arr = [1,2]

arr[2] // undefined, we can access index 2 even if this array doesn't have any value at index 2
 

Теперь в вашем коде вы написали цикл for для размера массива, в котором используется переменная с именем i . Итак, допустим , у вас есть массив json, длина которого равна 5. Итак, во время итерации, когда i == 5 , тогда [i 1] будет 6 и [i 2] будет 7. Но массив размеров не имеет этих индексов.

Подходы к решению для рассмотрения:


Вы можете использовать второй цикл for, как показано ниже, для каждой итерации внешнего цикла.

 for(let i=0; i<jsonSize; i  ) {
    for (let j=0; j<json[i].sizes; j  ) {
        // do things here
    }
}
 

Вы также можете просто использовать Array.prototype.forEach вместо циклов for. В этом случае вам нужно использовать одно предплечье внутри другого.

 JsonArr.forEach((eachElementObj,index)=>{
    //do outer loop things
    let sizes = eachElementObj.sizes
    sizes.forEach(element=>{
                    // do things 
    })
})