Track
/
jq
jq
/
Esercizi
/
Tabellone dei punteggi
Tabellone dei punteggi

Tabellone dei punteggi

Esercizio di apprendimento

Introduzione

Oggetti

Un oggetto JSON è, per usare la terminologia di altri linguaggi, un «hash», una «map» o un «dictionary».

JSON definisce un oggetto come:

Un oggetto è un insieme non ordinato di coppie nome/valore. Un oggetto inizia con la parentesi graffa aperta { e termina con la parentesi graffa chiusa }. Ogni nome è seguito dai due punti (:) e le coppie nome/valore sono separate da una virgola (,).

Il nome deve essere una stringa. Un altro termine per nome è chiave.

Il valore può essere di qualsiasi tipo JSON. Valori diversi nello stesso oggetto possono essere di tipi diversi, come in questo esempio.

{
  "name": "Jane",
  "age": 42,
  "pets": ["cat", "fish"],
  "address": {"street": "123 Main St", "city": "Springfield"}
}

Tieni presente che non deve esserci una virgola dopo l'ultima coppia chiave-valore.

Creare oggetti

Usa le parentesi graffe per raccogliere le coppie nome/valore. Anche se i nomi devono essere stringhe, non è necessario metterli tra virgolette se sono identifier-like (composti da caratteri alfanumerici e underscore, e non iniziano con una cifra).

{name: "Jane", age: 42}

È valido usare chiavi che non sono identifier-like. Basta metterle tra virgolette.

{"first name": "Jane", "last name": "Lopez", age: 42}

Se il nome è il risultato di un'espressione, l'espressione deve essere tra parentesi.

$ echo "Jane" | jq -Rc '{.: 42}'
# verbose error message ...

$ echo "Jane" | jq -Rc '{(.): 42}'
{"Jane":42}

Indicizzazione

I valori si recuperano da un oggetto con la notazione con il punto.

{name: "Jane", age: 42} | .age    # => 42

Se non puoi fare riferimento alla chiave come a un identificatore, usa la notazione con le parentesi.

"name" as $key | {name: "Jane", age: 42} | .$key    # => error
"name" as $key | {name: "Jane", age: 42} | .[$key]  # => "Jane"

Aggiungere o modificare coppie chiave-valore

Per aggiungere una nuova coppia chiave-valore a un array, o per aggiornare il valore di una chiave esistente, usa l'operatore di assegnazione =, con un'espressione di indice sul lato sinistro.

{name: "Jane", age: 42} | .sport = "tennis" | .age = 21
# => {
#      "name": "Jane",
#      "age": 21,
#      "sport": "tennis"
#    }

L'operatore + fonde gli oggetti.

{Richard: 54} + {Jane: 42}
# => {
#      "Richard": 54,
#      "Jane": 42
#    }

Rimuovere una chiave

Usa la funzione del per rimuovere una chiave. Restituisce l'oggetto aggiornato.

{name: "Jane", age: 42} | del(.age)   # => {"name": "Jane"}

Il parametro di del è un'espressione di indice (che usa la notazione con il punto o con le parentesi) che si risolve in una chiave dell'oggetto. jq la chiama espressione di percorso. Non basta fornire una semplice stringa.

{name: "Jane", age: 42} | del(name)        # error: name/0 is not defined
{name: "Jane", age: 42} | del("name")      # error: Invalid path expression with result "name"
{name: "Jane", age: 42} | del(.name)       # OK
{name: "Jane", age: 42} | del(.["name"])   # OK

Appartenenza

  • Per verificare se l'oggetto ha una chiave, usa la funzione has.

    {name: "Jane", age: 42} as $example
    |
      ($example | has("name")),    # => true
      ($example | has("sport"))    # => false
    
  • Verifica se una chiave è presente in un oggetto con in.

    {name: "Jane", age: 42} as $example
    |
      ("name"  | in($example)),    # => true
      ("sport" | in($example))     # => false
    

Elencare tutte le chiavi

Usa la funzione keys per produrre un elenco di tutte le chiavi.

{name: "Jane", age: 42} | keys   # => ["age", "name"]

Nota che keys ordina le chiavi. Per recuperare le chiavi nell'ordine originale, usa keys_unsorted.

Non esiste una funzione equivalente per elencare tutti i valori. Tuttavia il filtro .[] produce i valori dell'oggetto come stream, e quello stream può essere catturato con il costruttore di array [...].

[{first: "Jane", last: "Lopez", status: "awesome!"} | .[]]
# => ["Jane", "Lopez", "awesome!"]

Iterare

  • La funzione map_values(filter) applica il filtro a ogni valore dell'oggetto.

    {first: "Jane", last: "Lopez", status: "awesome!"}
    | map_values(ascii_upcase)
    # => {"first": "JANE", "last": "LOPEZ", "status": "AWESOME!"}
    
  • Per iterare su un oggetto, dobbiamo prima convertirlo in un array di oggetti chiave-valore. La funzione to_entries fa questo.

    {name: "Jane", age: 42} | to_entries'
    # => [
    #      {
    #        "key": "name",
    #        "value": "Jane"
    #      },
    #      {
    #        "key": "age",
    #        "value": 42
    #      }
    #    ]
    

    A questo punto, possiamo usare le funzioni di iterazione degli array, come map.

  • La funzione from_entries è l'inverso: converte un array di oggetti chiave-valore in un oggetto.

    [
      {"key":"name", "value":"Jane"},
      {"key":"age", "value":42}
    ] | from_entries                  # =>{"name": "Jane", "age": 42}
    
  • Per applicare un filtro a ogni coppia chiave-valore di un oggetto, usa la funzione with_entries(filter).

    Per esempio, dato un oggetto che associa un nome a un'età, le chiavi e i valori possono essere scambiati come segue.

    {"Jane": 42, "Richard": 54}
    | with_entries({key: (.value | tostring), value: .key})
    

    produce

    {
      "42": "Jane",
      "54": "Richard"
    }
    

    with_entries(filter) equivale a

    to_entries | map(filter) | from_entries
    

Istruzioni

In questo esercizio implementerai un modo per tenere traccia dei punteggi più alti del gioco più popolare della tua sala giochi locale.

Devi implementare 6 funzioni, per lo più legate alla manipolazione di un oggetto che contiene i punteggi più alti.

1. Crea una nuova classifica dei punteggi più alti

Scrivi una funzione create_score_board che crea un oggetto che funge da classifica dei punteggi più alti. Le chiavi di questo oggetto saranno i nomi dei giocatori, i valori saranno i loro punteggi. Per i test, vuoi includere direttamente una voce nell'oggetto. Questa voce iniziale deve consistere di "The Best Ever" come nome del giocatore e 1000000 come punteggio.

create_score_board
# returns an object with one initial entry

2. Aggiungi giocatori a una classifica

Per aggiungere un giocatore alla classifica dei punteggi più alti, implementa la funzione add_player. Prende in input una classifica e richiede due parametri: il nome del giocatore e il suo punteggio. La funzione dà in output l'oggetto classifica con il nuovo giocatore aggiunto.

{"José Valim", 486373}
| add_player("Dave Thomas"; 0)
# => {"Dave Thomas": 0, "José Valim": 486373} -- in some order

Se il giocatore è già presente nella classifica, dai in output la classifica invariata.

3. Rimuovi giocatori da una classifica

Se i giocatori violano le regole della sala giochi, vengono rimossi manualmente dalla classifica dei punteggi più alti. Implementa remove_player, che prende in input una classifica e un parametro: il nome del giocatore da rimuovere. Questa funzione deve rimuovere la voce del giocatore indicato dalla classifica e dare in output la nuova classifica. Se il giocatore non era presente nella classifica, non deve succedere nulla alla classifica: deve essere restituita così com'è.

{"Dave Thomas": 0} | remove_player("Dave Thomas")
# => {}

{"Dave Thomas": 0} | remove_player("Rose Fanaras")
# => {"Dave Thomas": 0}

4. Aumenta il punteggio di un giocatore

Se un giocatore termina un'altra partita alla sala giochi, una certa quantità di punti verrà aggiunta al punteggio precedente nella classifica. Implementa update_score, che prende in input una classifica e richiede due parametri: il nome del giocatore e la quantità di punteggio da aggiungere. La funzione deve restituire la classifica dopo l'aggiornamento.

{"Freyja Ćirić": 12771000} | update_score("Freyja Ćirić"; 73)
# => {"Freyja Ćirić": 12771073}

Questa funzione deve aggiungere il giocatore alla classifica se non era già presente.

5. Applica i punti bonus del lunedì

La sala giochi tiene una classifica separata il lunedì. Alla fine della giornata, ogni giocatore su quella classifica riceve 100 punti aggiuntivi.

Implementa la funzione apply_monday_bonus. La funzione aggiunge i punti bonus a ogni giocatore elencato in quella classifica.

{
  "Dave Thomas": 44,
  "Freyja Ćirić": 539,
  "José Valim": 265
}
| apply_monday_bonus
# => {"Dave Thomas": 144, "Freyja Ćirić": 639, "José Valim": 365}

6. Trova il punteggio totale

Sala giochi diverse competono tra loro per determinare chi ha i giocatori migliori. La sala giochi con il punteggio totale più alto vince l'onore.

Scrivi una funzione total_score. Prende in input una classifica e dà in output la somma dei punteggi di tutti i giocatori.

{
  "Dave Thomas": 44,
  "Freyja Ćirić": 539,
  "José Valim": 265
}
| total_score
# => 848
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
jq Exercism

Vuoi iniziare Tabellone dei punteggi?

Iscriviti a Exercism per imparare e padroneggiare jq con 12 concetti75 esercizi e il mentoring di persone reali, tutto gratis.