Obținerea unui singur element
Această lecție arată cum obții un element dintr-un tablou: după poziția sa, după o condiție sau la întâmplare. Arată și cum verifici dacă un element există.
TypeScript are două valori care înseamnă „nicio valoare”: null și undefined. Când o căutare poate eșua, răspunsul este undefined. Nu există un al doilea indicator lângă valoare: un element lipsă este undefined.
Citirea unei poziții care nu există, cum ar fi words[5] într-un tablou de 5 elemente, nu oprește programul. Primești undefined. Tipul string | undefined există tocmai ca să îți amintească de acest caz.
Ca să transformi acel undefined într-o valoare proprie, folosește operatorul ??. Acesta ia partea dreaptă doar când partea stângă este null sau undefined.
Tablourile au majoritatea acestor unelte ca metode: at(), find(), findLast(), includes() și every(). Pentru restul scrii o dată o mică funcție ajutătoare.
Obținerea după poziție
Fiecare element dintr-un tablou are o poziție numită index. Primul index este 0, deci ultimul este words.length - 1.
Ca să citești un element după poziție, scrie indexul între paranteze drepte: words[3]. Pentru ultimul element există și words.at(-1), care numără înapoi de la sfârșit.
Un index care nu există dă undefined în loc de eroare. Deci tipul corect al lui words[i] este string | undefined: poate există un șir, poate nu există nimic.
Nu există metoda elementAtOrNull() și nici elementAtOrElse(). Nu ai nevoie de ele: elementul lipsă este deja undefined, iar ?? pune valoarea ta în locul lui.
Elementul de la o poziție
words[3] citește elementul de la indexul 3. Deoarece numărarea începe de la 0, acesta este al patrulea cuvânt, deci programul afișează four.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
// Pozițiile încep de la 0, deci indexul 3 este al patrulea element.
console.log(words[3])
Primul și ultimul element
Primul element este words[0]. Ultimul este words.at(-1): at() acceptă un index negativ și numără înapoi de la sfârșit, deci -1 este ultimul element. Programul afișează one și apoi five.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
// Primul element este la indexul 0. at(-1) numără înapoi de la sfârșit.
console.log(words[0])
console.log(words.at(-1))
Elementul de la o poziție sau undefined
elementAt() doar citește items[i] și spune asta în tipul său de retur: T | undefined. Indexul 1 este în interval, deci primul apel afișează two. Indexul 5 este în afara intervalului, deci al doilea apel afișează undefined — fără eroare și fără un al doilea true sau false lângă valoare.
Ieșire: program TypeScript și rezultatul capturat
// Citirea unui index dă elementul sau undefined — nu există o a doua valoare „ok”.
function elementAt<T>(items: T[], i: number): T | undefined {
return items[i]
}
const words = ["one", "two", "three", "four", "five"]
console.log(elementAt(words, 1))
// Indexul 5 nu există: fără eroare, doar undefined.
console.log(elementAt(words, 5))
Elementul de la o poziție sau o valoare de rezervă
words[5] este undefined, deci ?? folosește partea dreaptă și apelează fallback(5). Funcția primește indexul, deci poate construi mesajul Valoarea pentru indexul 5 este undefined.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
const fallback = (i: number): string => `Valoarea pentru indexul ${i} este undefined`
// ?? folosește partea dreaptă doar când partea stângă este null sau undefined.
console.log(words[5] ?? fallback(5))
Obținerea după condiție
Deseori nu cunoști poziția. În schimb cunoști o condiție: primul cuvânt mai lung de 3 litere, ultimul cuvânt care începe cu "f". Condiția este o funcție care primește un element și returnează true sau false.
Pentru prima potrivire, tablourile au find(). Parcurge de la început și returnează primul element care trece testul sau undefined când niciunul nu trece.
findLast() face aceeași parcurgere în sens invers, de la ultimul index până la 0. Primul element pe care îl întâlnește este ultima potrivire din tablou.
Ambele metode se opresc imediat ce găsesc o potrivire, deci restul tabloului nu este testat niciodată. Și pentru că „nimic nu s-a potrivit” înseamnă pur și simplu undefined, testezi rezultatul cu !== undefined sau îi dai o valoare implicită cu ??.
Prima potrivire
find() returnează primul cuvânt cu s.length > 3. "one" și "two" sunt prea scurte, deci programul afișează three.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
// find() returnează primul element care trece testul.
console.log(words.find(s => s.length > 3))
Ultima potrivire
findLast() pornește de la ultimul index și coboară. Primul cuvânt întâlnit care începe cu "f" este "five", deci se oprește acolo și programul afișează five.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
// findLast() parcurge de la sfârșit, deci prima potrivire găsită este ultima din tablou.
console.log(words.findLast(s => s.startsWith("f")))
Prima potrivire sau undefined
Niciun cuvânt nu este mai lung de 6 litere, deci find() returnează undefined, iar ?? "nu a fost găsit" face programul să afișeze nu a fost găsit. În tabloul de numere, primul număr par este 2; verificarea !== undefined este modul în care programul știe că a găsit ceva.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
const numbers = [1, 2, 3, 4]
// Nimic nu se potrivește, deci find() returnează undefined și ?? oferă mesajul.
const long: string | undefined = words.find(s => s.length > 6)
console.log(long ?? "nu a fost găsit")
// „Găsit” înseamnă pur și simplu „nu este undefined”.
const firstEven: number | undefined = numbers.find(n => n % 2 === 0)
if (firstEven !== undefined) {
console.log(firstEven)
}
Ultima potrivire sau undefined
findLast() parcurge numerele înapoi, deci primul număr par pe care îl întâlnește este ultimul din tablou: 4, la indexul 3. Este găsit imediat.
Ieșire: program TypeScript și rezultatul capturat
const numbers = [1, 2, 3, 4]
// findLast() parcurge înapoi și returnează undefined când nimic nu se potrivește.
const lastEven: number | undefined = numbers.findLast(n => n % 2 === 0)
if (lastEven !== undefined) {
console.log(lastEven)
}
Obținerea primei valori prezente
Uneori un tablou are goluri: câteva elemente sunt null sau undefined, iar tu vrei prima valoare reală.
find() face din nou parcurgerea. Condiția este v !== null && v !== undefined.
Scris direct în funcția săgeată, rezultatul ar avea în continuare tipul number | string | null | undefined: testul rulează la execuție, dar tipul nu se schimbă. Mută testul într-o funcție cu nume al cărei tip de retur este v is number | string — o astfel de funcție se numește gardă de tip — și tipul rezultatului pierde de la sine null și undefined.
Tabloul din exemplu conține în același timp un număr, un șir și null, deci tipul său este o reuniune a tuturor acestora.
Prima valoare care nu este null sau undefined
Primul element este null, deci este sărit. Următorul este 0, care nu este nici null, nici undefined, deci find() îl returnează și se oprește — "true" nu este testat niciodată. Observă că 0 este păstrat: testul întreabă despre null și undefined, nu dacă valoarea este adevărată sau falsă.
Ieșire: program TypeScript și rezultatul capturat
// null și undefined înseamnă amândouă „nicio valoare”. Orice altă valoare contează.
const list: (number | string | null | undefined)[] = [null, 0, "true"]
// Fără „v is number | string” rezultatul ar păstra null și undefined în tipul său.
const isPresent = (v: number | string | null | undefined): v is number | string =>
v !== null && v !== undefined
const first: number | string | undefined = list.find(isPresent)
console.log(first)
Element aleatoriu
Ca să alegi un element aleatoriu, alege un index aleatoriu. Un index valid este un număr întreg de la 0 până la numbers.length - 1.
Tablourile nu au o metodă random(), deci indexul intră între paranteze drepte, ca de obicei.
Math.random() dă un alt număr la fiecare rulare. Asta îți dorești într-un program real, dar ar face ca această lecție să afișeze altceva de fiecare dată. De aceea exemplul își inițializează propriul generator minuscul cu numărul fix 42. Aceeași sămânță produce mereu același index, ceea ce face rezultatul reproductibil. Folosește Math.random() când chiar vrei un alt element la fiecare rulare.
Alegerea unui element aleatoriu
Cu sămânța 42, generatorul alege indexul 1, deci programul afișează 2. Schimbă sămânța și poate ieși alt număr.
Ieșire: program TypeScript și rezultatul capturat
const numbers = [1, 2, 3, 4]
const MOD = 4294967296
let seed = 42
// Un mic generator propriu: aceeași sămânță dă mereu același index.
function nextIndex(n: number): number {
seed = (seed * 1664525 + 1013904223) % MOD
return Math.floor((seed / MOD) * n)
}
const i = nextIndex(numbers.length)
console.log(numbers[i])
Verificarea existenței unui element
Ca să verifici dacă o valoare se află într-un tablou, folosește includes(). Returnează true sau false.
Nu există o metodă containsAll(), dar every() îți oferă una într-o singură linie: wanted.every(v => words.includes(v)) este true doar când fiecare valoare căutată este găsită. every() se oprește la prima valoare care lipsește.
Nu există nici isEmpty(). Compară lungimea: words.length === 0 înseamnă gol, words.length > 0 înseamnă că nu este gol.
Conține o valoare
"four" se află în tablou, deci prima verificare afișează true. "zero" nu se află, deci a doua afișează false.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
console.log(words.includes("four"))
console.log(words.includes("zero"))
Conține toate valorile
Atât "four", cât și "one" se află în tablou, deci containsAll() returnează true. "zero" lipsește, deci al doilea apel returnează false.
Ieșire: program TypeScript și rezultatul capturat
// every() este true doar când testul trece pentru fiecare valoare căutată.
function containsAll<T>(items: T[], wanted: T[]): boolean {
return wanted.every(v => items.includes(v))
}
const words = ["one", "two", "three", "four", "five"]
console.log(containsAll(words, ["four", "one"]))
console.log(containsAll(words, ["one", "zero"]))
Gol sau nu este gol
empty are lungimea 0, deci empty.length === 0 este true. words are 5 elemente, deci words.length > 0 este de asemenea true.
Ieșire: program TypeScript și rezultatul capturat
const words = ["one", "two", "three", "four", "five"]
const empty: string[] = []
// Un tablou este gol când lungimea sa este 0.
console.log(empty.length === 0)
console.log(words.length > 0)