Как я могу получить первое изображение из каждого альбома с четным идентификатором в React с помощью Fetch?

У меня есть API, который возвращает 5000 изображений. Я хочу получить первое изображение из каждого альбома с четным идентификатором в React с помощью Fetch.

Проблема в том, что не могу понять, как фильтровать данные, чтобы получить те, у которых есть четные идентификаторы и первое изображение альбомов с четными идентификаторами.

import React, {useState, useEffect} from 'react';

// Import Materials from Material-ui
import {Grid} from '@material-ui/core';


const Album = () => {
    const [images, setImages] = useState([]);
    const [imagesCount, setImagesCount] = useState(10);
    const api = 'https://jsonplaceholder.typicode.com/photos';

    useEffect(() => {
        fetch(api)
        .then(res => res.json())
        .then(data => {
          const filterData = data.filter(x => x.albumId % 2 === 0);
          for(const url of filterData) {
            if (url.albumId % 2 === 0) {
              // How to get only the first even ablumID url of each even albumID?
            }
          }
          setImages(filterData);
          console.info(filterData);
        })
        .catch(err => console.info(err))

      }, []);

    return (
        <div>
        <Grid container spacing = {3} alignItems = "center">
          {images.map((album) => (
            <Grid item key = {album.id} xs = {12} sm = {6} md = {4}>
              <img className = "albumImg" src = {album.url} alt = {album.title} />
            </Grid>
          ))}
        </Grid>
        </div>
    )
}

export default Album;

Так в чем проблема, с которой вы столкнулись? Кстати, Array.prototype.filter возвращает новый массив и не изменяет старый массив, поэтому, если вы хотите вызвать setImages для отфильтрованного массива, вам следует сохранить этот новый массив в переменной и использовать ее для установки вашего state.

goto 15.12.2020 00:42

data.filter(x => x.albumId % 2 === 0) на самом деле ничего не фильтрует.

Rastezzy 15.12.2020 00:44

Смотрите мой обновленный комментарий.

goto 15.12.2020 00:44

data.filter(x => x.albumId% 2 === 0); вы пытаетесь отфильтровать идентификаторы, которые являются четными числами, или вы пытаетесь получить идентификатор === 0?

Nonik 15.12.2020 00:46

Я пытаюсь отфильтровать идентификаторы с четными числами.

Rastezzy 15.12.2020 00:48

Вы пробовали то, что я предложил?

goto 15.12.2020 00:49

Как сказал @goto1, вам нужно назначить результат этого фильтра. data = data.filter(x => x.albumId % 2 === 0);developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Ashley 15.12.2020 00:50

@goto1 goto1 Я сделал то, что вы предложили, добавив к константе - const filterData = data.filter(x => x.albumId % 2 === 0); и добавил в setImages, ничего не изменилось. Я все еще получаю 5000 альбомов без фильтрации.

Rastezzy 15.12.2020 00:54

Я обновил свой код в своем вопросе

Rastezzy 15.12.2020 00:57

Это определенно должно помочь - это работает на моем конце. Что вы получаете, когда вы console.info(data.length) против console.info(filteredData.length)?

goto 15.12.2020 01:05

@ goto1, это определенно помогло! Я смотрел журнал из данных, а не из filterData, oppps, спасибо. Теперь, как я могу получить только первое изображение из каждого четного альбома?

Rastezzy 15.12.2020 01:11

Не уверен, что вы имеете в виду, вы говорите массив urls? Это то, что вы хотите для массива images?

goto 15.12.2020 01:13

Да, я хочу получить первый URL-адрес каждого первого четного массива. Таким образом, URL-адрес первого изображения из альбомного идентификатора 2, 4 и 6 и т. д., но только первое изображение из каждого четного альбомного идентификатора.

Rastezzy 15.12.2020 01:17

Смотрите мой ответ ниже.

goto 15.12.2020 01:31
Поведение ключевого слова "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) для оценки ваших знаний,...
0
14
659
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что касается первой проблемы, Array.prototype.filter не изменяет существующий массив, а вместо этого возвращает новый массив с элементами, которые проходят тест, поэтому вам нужно сохранить этот новый массив в переменной и использовать ее для обновления вашего состояния,

const api = "https://jsonplaceholder.typicode.com/photos";

fetch(api)
  .then((res) => res.json())
  .then((data) => {
    const filterData = data.filter((x) => x.albumId % 2 === 0);

    console.info("original", data.length);
    console.info("filtered", filterData.length);
  })
  .catch((err) => console.info(err));

Что касается вашей второй проблемы, если вы хотите создать новый массив с элементами, которые имеют уникальные albumIds, вы можете использовать Array.prototype.reduce для перебора всех элементов и добавления только тех, которых еще нет в accumulator,

const api = "https://jsonplaceholder.typicode.com/photos";

fetch(api)
  .then((res) => res.json())
  .then((data) => {
    const filterData = data.filter((x) => x.albumId % 2 === 0);
    const uniqueItems = filterData.reduce((accumulator, item) => {
      const isDuplicateItem = accumulator.find(
        (i) => i.albumId === item.albumId
      );
      // append the item if there's no existing
      // item in the array with the same `albumId`
      if (!isDuplicateItem) {
        return [...accumulator, item];
      }

      return accumulator;
    }, []);

    console.info("uniqueItems", uniqueItems.length);
    console.info(uniqueItems[0]);
    console.info(uniqueItems[1]);
  })
  .catch((err) => console.info(err));

Смотрите больше, если нужно:

Но как я могу получить только первый массив каждого четного массива?

Rastezzy 15.12.2020 01:54

@Rastezzy, можете ли вы уточнить, что вы подразумеваете под «первым массивом каждого четного массива»? Вы перебираете массив объектов со следующими свойствами: {albumId: number, id: number, title: string, url: string, thumbnailUrl: string}. О каком array ты говоришь?

goto 15.12.2020 01:58

Извините за плохое использование терминов, я имел в виду объекты. Теперь, поскольку у нас есть несколько объектов с похожими альбомными идентификаторами, мне просто нужен URL-адрес из первого альбомного идентификатора только первого четного числа. Таким образом, первый URL-адрес первого объекта только с альбомным идентификатором 2, а не остальные с альбомным идентификатором 2 и т. д. Имеет ли это смысл?

Rastezzy 15.12.2020 02:05

Я обновил свой код, это самый близкий к ответу ответ.

Rastezzy 15.12.2020 02:16

@Rastezzy, посмотри мое редактирование - я думаю, это то, что ты ищешь.

goto 15.12.2020 02:25

@Rastezzy Я только что понял, что это должно быть filterData.reduce, а не data.reduce - вам нужен уникальный albumIds только для тех, у кого четные числа, поэтому я внес изменения, но вы поняли идею.

goto 15.12.2020 02:34

Я уже сделал это в своем коде, да, я понял.

Rastezzy 15.12.2020 02:58

Я этого не делал, не знаю почему, но отмечу заново.

Rastezzy 15.12.2020 18:24

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