Kurzusok
/
jq
jq
/
Feladatok
/
Jegyek statisztikái
Jegyek statisztikái

Jegyek statisztikái

Tanulófeladat

Bevezetés

Reduce

Tegyük fel, hogy össze szeretnénk adni egy számtömböt. Ezt a célt többféleképpen is elérhetjük.

  • Sok nyelvben ezt a problémát egy ciklussal és egy akkumulátorváltozóval fejezik ki.

  • Ez a probléma rekurzív függvényként is megírható. Pszeudokódban valahogy így nézhet ki.

    function Add(X, Sum=0):
      if X is empty then
        return Sum
      else
        return Add(rest(X), Sum + first(X))
      end
    end
    

    Ez a problémafelosztási módszer úgy is leírható, mint „redukálás az alapeset felé”.

A Reduce olyan módszer, amellyel egy adatszerkezet összes elemét egyetlen értékké lehet összevonni. A folyamat végigiterál az adatszerkezeten, minden elemre alkalmazva egy függvényt, hogy frissítse a felhalmozott eredményt.

A jq-ban ezt a folyamatot a reduce szűrő valósítja meg. Más nyelvekben lehet, hogy „fold”, „fold-left”, „inject” vagy „aggregate” a neve.

A jq reduce kifejezése így néz ki.

reduce STREAM_EXPRESSION as $var (INITIAL_VALUE; UPDATE_EXPRESSION)
  • A STREAM_EXPRESSION elemek egy stream-je, amelyek sorra a $var változóba kerülnek.
  • Az INITIAL_VALUE a felhalmozott eredmény kezdőértéke (ezt nevezik „akkumulátornak”).
  • Az UPDATE_EXPRESSION összevonja („belehajtja”) az aktuális értéket ($var) az akkumulátorba.
    • Ebben a kifejezésben a . az akkumulátor értéke.
    • A kifejezés kimenete az akkumulátorba kerül, és a következő iterációban használjuk fel.
    • Az utolsó iteráció után a felhalmozott eredmény lesz a reduce kimenete.

Nézzünk egy példát: adjuk össze egy tömb számait. Az add szűrő pontosan ezt csinálja, de lássuk, hogyan lehet megvalósítani.

Ha a [10, 20, 30, 40] a bemenet, és a kezdőállapot nulla, akkor az egyes lépések így néznek ki.

# állapot elem redukáló eredmény
1 0 10 0 + 10 10
2 10 20 10 + 20 30
3 30 30 30 + 30 60
4 60 40 60 + 40 100

jq-szintaxisban ez így néz ki.

0 + 10 | . + 20 | . + 30 | . + 40

Ezt a reduce szűrővel fejezhetjük ki.

[10, 20, 30, 40] | reduce .[] as $n (0; . + $n)     # => 100
Note

Az add beépített valójában a reduce-dzsal van megvalósítva, de „null”-t használ kezdőállapotként (bármilyen adattípus hozzáadható a nullhoz).

def add: reduce .[] as $x (null; . + $x);

Néhány dolog, amire érdemes figyelni

  • A redukáló kifejezésben a . az akkumulátor. Ha a bemenet egy olyan objektum, amire a redukáló függvényen belül hivatkozni szeretnél, el kell tárolnod egy változóban.

    {"apple": 10, "banana": 16, "carrot": 4}
    | . as $obj
    | reduce (keys | .[]) as $key (0; . + $obj[$key])     # => 30
    
  • Az akkumulátor bármilyen adattípusú lehet. Például meg szeretnél fordítani egy tömböt.

    ["A", "B", "C", "D"]
    | reduce .[] as $elem ([]; [$elem] + .)       # => ["D", "C", "B", "A"]
    

Utasítások

Tanár vagy. Az év végén minden tanulódhoz kiszámoltál egy numerikus osztályzatot. Most át kell alakítanod ezeket betűjegyekké, és meg kell számolnod, hány tanuló érte el az egyes betűjegyeket.

1. Alakítsd át a numerikus osztályzatot betűjeggyé

A letter_grade függvény bemenetként egy numerikus osztályzatot kap, és kiadja a hozzá tartozó betűt. Ezeket a tartományokat használd:

Betű Osztályzat
A 90% - 100%
B 80% - 89%
C 70% - 79%
D 60% - 69%
F 0% - 59%

Példa:

75 | letter_grade   # => "C"

2. Számold meg az egyes betűjegyekhez tartozó tanulók számát

A count_letter_grades függvény egy olyan objektumot kap, amely a tanulók nevét az osztályzataikhoz rendeli. A kimenet egy olyan objektum lesz, amely minden betűjegyhez a hozzá tartozó tanulók számát rendeli.

Példa:

{"Joe": 78, "Jane": 93, "Richard": 72} | count_letter_grades
# => {"A": 1, "B": 0, "C": 2, "D": 0, "F": 0}

Ezt többféleképpen is meg lehet oldani. Gyakorlásként használd a reduce szűrőt.

Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
jq Exercism

Készen állsz elkezdeni a(z) Jegyek statisztikái feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) jq nyelvet 12 fogalom75 feladat segítségével, valódi emberi mentorálással, mindez ingyen.