Treci la conținutul principal

Filtrarea unei colecții

Filtrarea înseamnă alegerea elementelor dintr-o colecție care îndeplinesc o condiție.

Condiția se scrie ca o funcție care primește un element și returnează true (îl păstrăm) sau false (îl sărim). O astfel de funcție se numește predicat.

Filtrarea construiește un slice nou. Slice-ul original nu este modificat.

Go nu are o metodă filter încorporată pentru slice-uri. Filtrezi cu o buclă for și un if, sau scrii o singură dată un mic helper generic și îl refolosești. Helper-ul de mai jos funcționează pentru un slice de orice tip.

Biblioteca standard are slices.DeleteFunc(), care elimină elementele ce îndeplinesc o condiție. Ai grijă: aceasta modifică slice-ul original în loc să creeze unul nou.

Sintaxa helper-ului generic Filter

T reprezintă tipul elementelor. keep este predicatul: elementele pentru care returnează true sunt copiate în result.

main.go
func Filter[T any](items []T, keep func(T) bool) []T {
  var result []T
  for _, v := range items {
    if keep(v) {
      result = append(result, v)
    }
  }
  return result
}

Filtrare cu un predicat

Cel mai simplu mod de a filtra este să pasezi un predicat helper-ului Filter. Helper-ul parcurge slice-ul și păstrează fiecare element care trece testul.

Map-urile nu au un helper propriu. Ca să filtrezi un map, parcurge-l cu range și copiază perechile cheie:valoare potrivite într-un map nou.

Dacă în condiție ai nevoie și de poziția elementului, folosește indexul dat de range împreună cu valoarea.

Ca să păstrezi elementele care nu îndeplinesc condiția, pune ! în fața condiției. Go nu are un filterNot separat.

Un slice de tip []any poate conține valori de tipuri diferite. O aserțiune de tip precum v.(string) verifică dacă o valoare este un string și o dă înapoi cu acel tip. Un pointer poate fi nil, ceea ce înseamnă „nicio valoare”; compară cu nil ca să sari peste astfel de intrări.

Filtrarea unui slice

Păstrează doar cuvintele mai lungi de 3 litere. Condiția len(s) > 3 este pasată lui Filter ca funcție.

Prompt
Scrie un helper generic Filter care primește un slice și o funcție-condiție și returnează un slice nou cu doar elementele care trec testul. Folosește-l pe cuvintele one, two, three, four ca să păstrezi cuvintele mai lungi de 3 litere. Afișează rezultatul.
Ieșire: program Go și rezultatul capturat
Filter a slice

Filtrarea unui map

Parcurge map-ul și păstrează perechile a căror cheie se termină cu "1" și a căror valoare este mai mare decât 10. strings.HasSuffix() verifică sfârșitul unui string.

Prompt
Creează un map de la cheile key1, key2, key3, key11 la valorile 1, 2, 3, 11. Parcurge-l și copiază într-un map nou doar perechile a căror cheie se termină cu "1" și a căror valoare este mai mare decât 10. Afișează map-ul nou.
Ieșire: program Go și rezultatul capturat
Filter a map

Filtrare folosind indexul

range dă indexul și valoarea. Păstrează un cuvânt doar când indexul lui nu este 0 și are mai puțin de 5 litere.

Prompt
Ia cuvintele one, two, three, four. Parcurge-le cu range ca să obții atât indexul, cât și cuvântul. Păstrează un cuvânt doar dacă indexul lui nu este 0 și dacă are mai puțin de 5 litere. Afișează cuvintele păstrate.
Ieșire: program Go și rezultatul capturat
Filter using the index

Filtrare cu o condiție negată

Elimină cuvintele cu 3 litere sau mai puține. Condiția len(s) = 3 este negată cu !, așa că rămân doar cuvintele mai lungi.

Prompt
Ia cuvintele one, two, three, four. Folosește un helper generic Filter, dar neagă condiția cu ! astfel încât cuvintele cu 3 litere sau mai puține să fie eliminate. Afișează rezultatul.
Ieșire: program Go și rezultatul capturat
Filter with a negated condition

Filtrare după tip

Slice-ul conține nil, un număr, două string-uri și un float. Aserțiunea de tip v.(string) împreună cu valoarea ok găsește string-urile. Fiecare este afișat cu majuscule.

Prompt
Creează un slice de tip []any care conține nil, 1, "two", 3.0 și "four". Parcurge-l și folosește o aserțiune de tip ca să găsești valorile care sunt string-uri. Afișează fiecare string cu majuscule, câte unul pe linie.
Ieșire: program Go și rezultatul capturat
Filter by type

Eliminarea valorilor nil

Slice-ul conține pointeri către string-uri, iar unii dintre ei sunt nil. Păstrează pointerii care nu sunt nil și adună valorile către care arată cu *p.

Prompt
Creează un slice de pointeri către string-uri care conține nil, un pointer către "one", nil și un pointer către "two". Păstrează doar pointerii care nu sunt nil și adună string-urile către care arată. Afișează slice-ul adunat.
Ieșire: program Go și rezultatul capturat
Filter out nil values

Partiționare

Uneori vrei ambele grupuri: elementele care îndeplinesc condiția și cele care nu o îndeplinesc.

Go nu are un partition încorporat. Un mic helper generic face asta: parcurge o singură dată și adaugă fiecare element fie în slice-ul match, fie în slice-ul rest. Helper-ul returnează ambele slice-uri, pentru că o funcție Go poate returna mai multe valori.

Împărțirea unui slice în două

Cuvintele mai lungi de 3 litere ajung în match; toate celelalte ajung în rest. Ambele slice-uri sunt afișate.

Prompt
Scrie un helper generic Partition care împarte un slice în două: elementele care îndeplinesc o condiție și restul. Folosește-l pe cuvintele one, two, three, four cu condiția „mai lung de 3 litere”. Afișează slice-ul cu elementele potrivite, apoi restul.
Ieșire: program Go și rezultatul capturat
Split a slice in two

Predicate de verificare

Uneori nu ai nevoie de elementele potrivite, ci doar de un răspuns da sau nu.

  • any: trece cel puțin un element testul? slices.ContainsFunc() din Go răspunde la această întrebare.
  • none: nu trece niciun element testul? Pune ! în fața lui slices.ContainsFunc().
  • all: trece fiecare element testul? Go nu are o funcție pentru asta, așa că folosește un mic helper generic All.

Fără o condiție, „există vreun element?” înseamnă len(s) > 0, iar „nu există niciun element?” înseamnă len(s) == 0.

Pe un slice gol, All returnează true. Nu există niciun element care să cadă testul, deci testul nu este încălcat niciodată. Aceasta se numește adevăr vid.

any

Verifică dacă cel puțin un cuvânt se termină cu "e", apoi verifică dacă slice-ul are vreun element.

Prompt
Ia cuvintele one, two, three, four. Folosește slices.ContainsFunc ca să verifici dacă cel puțin un cuvânt se termină cu "e" și afișează răspunsul. Apoi afișează dacă slice-ul are vreun element, verificând că lungimea lui este mai mare decât 0.
Ieșire: program Go și rezultatul capturat
any

none

Verifică faptul că niciun cuvânt nu se termină cu "a", apoi verifică dacă slice-ul este gol.

Prompt
Ia cuvintele one, two, three, four. Folosește ! împreună cu slices.ContainsFunc ca să verifici că niciun cuvânt nu se termină cu "a" și afișează răspunsul. Apoi afișează dacă slice-ul este gol, verificând că lungimea lui este egală cu 0.
Ieșire: program Go și rezultatul capturat
none

all

Verifică dacă fiecare cuvânt se termină cu "e". Apoi apelează All pe un slice gol, ceea ce dă true.

Prompt
Scrie un helper generic All care returnează true doar când fiecare element al unui slice îndeplinește o condiție. Verifică dacă toate cuvintele one, two, three, four se termină cu "e" și afișează răspunsul. Apoi apelează All pe un slice gol cu aceeași condiție și afișează răspunsul.
Ieșire: program Go și rezultatul capturat
all