• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Liczenie danych na podstawie listy obiektów w React

Object Storage Arubacloud
0 głosów
230 wizyt
pytanie zadane 6 grudnia 2022 w JavaScript przez DzikieHarce Użytkownik (690 p.)

Napisałam prosty serwer, zwracający mi do reactowej aplikacji (pisanej w javaScripcie) listę zwierząt danego użytkownika i listę gatunków. Każde zwierzę jest przypisane do gatunku. Przykładowe zwierzę (jest to obiekt z listy, zwracany z zapytania o zwierzęta użytkownika):

age: 2

avg_length_of_life: 16 <- jest to średnia długość życia gatunku, nie zwierzęcia!

characteristics: "Nice, soft and furry!"

id: 17

name: "Puszek"

occurrence: "Worldwide!"

specieName: "Cat"

Chciałabym policzyć, ile dany użytkownik ma zwierząt z każdego gatunku (nie są one zahardcodowane, więc lista powinna być tworzona na bieżąco), oraz jaka jest średnia długość życia dla zwierząt poszczególnych gatunków.

Dane pobieram w useEffect, za pomocą Axiosa, więc wydaje mi się, że powinnam użyć czegoś, co uruchomi się po ich zebraniu i ustawieniu za pomocą set:

const [animals, setAnimals] = useState([]);

Mam pewność, że dane zbierane są poprawnie (w innym komponencie je wyświetlam i nie ma problemu).

Wydaje mi się, że funkcja powinna najpierw tworzyć tabelę z nazwami gatunków, a potem doliczać do niej liczę, czy średnią wieku. Nie wiem tylko, w którym momencie funkcje powinna się wywoływać. Na razie mam  tyle:

const [posts, setPosts] = useState([]);

//Na pewno działa, testowałam
useEffect(()=>{  
      const fetchPosts = async () =>{
        try{
        const response = await axios.get(SPECIE_URL);
        if (response && response.data) setPosts(response.data);
      }
    catch(err){
      if(!err?.response){
        console.log("Something goes wrong");
      }
    }
  }
    fetchPosts();
  },[]);

function getData(){
    var specieTable;
    
      for (let i=0; i<posts.length; i++){
        posts.map((specie)=>(
      specieTable[i] = specie.name  
      ))
      console.log(specieTable)}

  }

Listę zwierząt pobieram w podobny sposób i przechowuję je za pomocą useState.

1 odpowiedź

+2 głosów
odpowiedź 6 grudnia 2022 przez rafal.budzis Szeryf (85,260 p.)
wybrane 13 grudnia 2022 przez DzikieHarce
 
Najlepsza

To czego Ci brakuje to albo nowy useState i wywoływać to w kolejnym useEffect lub return i wywoływanie w JSX. Tu masz przykład jak mogło by to wyglądać w 2 przypadku. 
 

function getData(){
     const specieTable = {};
     posts.forEach((specie)=>{
          specieTable[specie.name] =  (specieTable[specie.name] || 0) +1
     })
      return Object.entries(specieTable);
}

[...]


return <div>
    {getData().map(([name, count]) => <span>{name} - {count}</span>)}
</div>

 

1
komentarz 6 grudnia 2022 przez rafal.budzis Szeryf (85,260 p.)
PS. skoro avg_length_of_life jest wartością całego gatunku a nie kota to dobrze by było trzymać ją w osobnym obiekcie i odwoływać się do niego np po nazwie gatunku ;)
komentarz 13 grudnia 2022 przez DzikieHarce Użytkownik (690 p.)
Dzięki za pomoc i przepraszam za późną odpowiedź. Chyba rozumiem jak to ugryźć, postaram się dodać tu komentarz z ewentualnym kodem.

Co do avg_length_of_life to masz rację, to również postaram się załatwić.

Dziękuję.
komentarz 13 grudnia 2022 przez rafal.budzis Szeryf (85,260 p.)
Cieszę się że mogłem pomóc :)
komentarz 26 grudnia 2022 przez DzikieHarce Użytkownik (690 p.)
edycja 26 grudnia 2022 przez DzikieHarce

Ok, przetestowałam i działa ;P Jakbym tylko mogła dopytać, bo rozumiem że nowo utworzona tabela wygląda mniej więcej tak:

{

Cat: 1

Horse: 3

}

i tak dalej. A da się z niej zrobić tablicę obiektów? Czyli, żeby wyglądała tak:

{

name: Cat,

count: 1

},

{

name: Horse,

count: 3

)

Myślałam, żeby w useEffect zrobić coś takiego, ale wygląda to dość śmiesznie i raczej nie ma prawa działać:

posts.forEach((specie)=>{
    newTable = {
    name: specie.name,
    count: (newTable[count] || 0) +1
    }
  })

 

komentarz 26 grudnia 2022 przez DzikieHarce Użytkownik (690 p.)

Udało mi się zrobić coś takiego, ale nadal źle zlicza

 response.data.forEach((specie)=>{
            var singleObj = {};
            singleObj['name'] = specie.specieName;
            singleObj['count'] = (newTable.forEach((obj)=>{if(obj.name == specie.specieName) return obj.count}) || 0) +1;
            newTable.push(singleObj);
          })
          console.log(newTable);
          setTable(newTable);

 

1
komentarz 27 grudnia 2022 przez rafal.budzis Szeryf (85,260 p.)

Do zmiany formatu danych w tablicy służy funkcja map. 

Wystarczy dopisać 

.map(([name, count]) => ({name, count}))

W odpowiednim miejscu ;) 

Zwróć też uwage że użyłem funkcji Object.entries która powinna ci zamienić całość na format składający się tylko z tablic.

[
    ["Cat", 1],
    ["Horse", 3]
]


 

function getData(){
     const specieTable = {};
     posts.forEach((specie)=>{
          specieTable[specie.name] =  (specieTable[specie.name] || 0) +1
     })

     const formated = Object.entries(specieTable).map(([name, count]) => ({name, count}))

     return formated;
}

 

1
komentarz 27 grudnia 2022 przez DzikieHarce Użytkownik (690 p.)
A ja się tak męczyłam ;P Dzięki wielkie ;P
komentarz 28 grudnia 2022 przez rafal.budzis Szeryf (85,260 p.)
Nie ma sprawy ;) Próbowanie samemu też jest ważne bo zbierasz doświadczenie ;)
komentarz 30 grudnia 2022 przez DzikieHarce Użytkownik (690 p.)
Tak, chociaż się czegoś nauczyłam, dzięki raz jeszcze ;P

Podobne pytania

0 głosów
1 odpowiedź 212 wizyt
+1 głos
0 odpowiedzi 117 wizyt
0 głosów
1 odpowiedź 189 wizyt

92,555 zapytań

141,403 odpowiedzi

319,554 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...