• 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

VPS Starter Arubacloud
0 głosów
215 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ź 194 wizyt
+1 głos
0 odpowiedzi 110 wizyt
0 głosów
1 odpowiedź 184 wizyt

92,454 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...