Ders 17 / 21
Diziler
Dizi oluşturma yolları ve boşluklar, dizin erişimi, değiştiren ve değiştirmeyen yöntemlerin ayrımı, sıralama tuzağı ve dönüştürme zincirleri.
İçindekiler
Önceki konuda filter, map ve split gibi yöntemler açıklanmadan kullanıldı. Bu konu
onları tanımlıyor. Veri Yapıları kursunda dizinin iç yapısı, maliyeti ve dinamik dizinin
amortize davranışı incelenmişti; burada JavaScript’in dizi nesnesinin somut davranışı ve
tuzakları ele alınacak.
JavaScript dizisi, Veri Yapıları kursundaki bitişik bellek modelinin birebir karşılığı
değildir. typeof sonucu object’tir; dizinleri anahtar olarak taşıyan, length
özelliği kendini güncelleyen özel bir nesnedir. Bu ayrım birkaç davranışı doğrudan
açıklar.
Oluşturma
const dogrudan = [21.5, 19.75, 23]; const bosluklu = new Array(3); const tekEleman = Array.of(3); const metinden = Array.from("A1"); const uretilen = Array.from({ length: 3 }, (_, i) => i * 10); console.log(dogrudan, dogrudan.length); console.log(bosluklu, bosluklu.length); console.log(tekEleman, metinden); console.log(uretilen); console.log(Array.isArray(dogrudan), typeof dogrudan);
[ 21.5, 19.75, 23 ] 3 [ <3 empty items> ] 3 [ 3 ] [ 'A', '1' ] [ 0, 10, 20 ] true object
İkinci satır bir tuzağı gösteriyor: tek sayısal argümanla çağrılan yapıcı, o değeri
eleman yapmaz, o uzunlukta boş bir dizi üretir. Array.of bu belirsizliği ortadan
kaldırır ve argümanı eleman sayar.
Array.from iki iş yapar: yinelenebilir bir değeri diziye çevirir ve length alanı olan
bir nesneden dizi üretir. İkinci argümanı, her eleman için çağrılan bir eşleme
fonksiyonudur. Alt çizgi adı, kullanılmayan parametre için seçilmiş bir yazım
sözleşmesidir; dilin kuralı değildir.
Son satır tip gözlemidir: bir değerin dizi olup olmadığı typeof ile anlaşılmaz,
Array.isArray ile sınanır.
Boşluklar
Bir dizinin bazı dizinlerinde eleman hiç bulunmayabilir. Bu boşluklar (holes),
undefined değeri taşıyan elemanlardan farklıdır:
const bosluklu = new Array(3); console.log(bosluklu[0], 0 in bosluklu); console.log(bosluklu.map(() => 1)); console.log(Array.from({ length: 3 }, () => 1));
undefined false [ <3 empty items> ] [ 1, 1, 1 ]
İlk satır ayrımı gösteriyor: okuma undefined verdi, ama dizin dizide yok. İkinci
satır sonucudur: eşleme yöntemi boşlukları atlar, geri çağrı hiç çalışmaz. Üçüncü satır
doğru yoldur.
Boşluklar dizine doğrudan yazarak da oluşur:
const dizi = [21.5, 19.75]; dizi.length = 1; console.log(dizi); dizi[4] = 99; console.log(dizi, dizi.length);
[ 21.5 ] [ 21.5, <3 empty items>, 99 ] 5
length alanına yazmak diziyi kırpar. Uzunluğun ötesindeki bir dizine yazmak ise
aradaki dizinleri boş bırakır ve length değerini büyütür. Kursun kuralı: diziler
boşluklu bırakılmaz; ekleme push ile, üretme Array.from ile yapılır.
Çıktıdaki <3 empty items> gösterimi çalışma zamanının inceleme biçimidir; boşluğu
undefined değerinden ayırt etmek için kullanılır ve ortamlar arasında değişir.
Erişim ve Arama
const s = [21.5, 19.75, 23, 18.25]; console.log(s[0], s[s.length - 1], s.at(-1), s.at(-2)); console.log(s[10]); console.log(s.indexOf(23), s.includes(23)); const nanli = [NaN, 1]; console.log(nanli.indexOf(NaN), nanli.includes(NaN));
21.5 18.25 18.25 23 undefined 2 true -1 true
Aralık dışı dizin hata vermez, undefined verir. at yöntemi negatif dizin kabul eder
ve sondan sayar.
Son satır, Eşitlik Karşılaştırmaları dersinde bırakılan bir ipucunun karşılığıdır:
indexOf katı eşitlik kullanır ve NaN hiçbir şeye eşit olmadığı için bulunamaz;
includes ise değer eşitliğine yakın bir bağıntı kullanır ve NaN bulur. İki yöntem
aynı soruyu sormaz.
Değiştiren ve Değiştirmeyen Yöntemler
Diziler değiştirilebilir nesnelerdir. Yöntemler iki sınıfa ayrılır ve hangi sınıfta olduğunu bilmemek, paylaşılan veride sessiz hatalar üretir.
Değiştiren yöntemler diziyi yerinde günceller: push, pop, shift, unshift,
splice, sort, reverse, fill.
Değiştirmeyen yöntemler yeni bir dizi döndürür: slice, concat, map, filter,
flat, toSorted, toReversed.
const asil = [21.5, 19.75, 23]; const kopya = asil.slice(); kopya.push(18.25); console.log(asil, kopya); const ters = asil.toReversed(); console.log(asil, ters); const yerinde = [...asil]; yerinde.reverse(); console.log(yerinde);
[ 21.5, 19.75, 23 ] [ 21.5, 19.75, 23, 18.25 ] [ 21.5, 19.75, 23 ] [ 23, 19.75, 21.5 ] [ 23, 19.75, 21.5 ]
Yayma sözdizimiyle ([...asil]) veya slice ile alınan kopya sığdır: dizinin
kendisi yenidir, ama elemanlar aynı nesnelerdir. Programlama Temelleri kursundaki sığ
kopya–derin kopya ayrımı burada geçerlidir; nesne dizilerinde eleman üzerinde yapılan
değişiklik her iki diziden de görülür.
Sıralama Tuzağı
sort yöntemi, karşılaştırma fonksiyonu verilmediğinde elemanları metne çevirip
sözlük sırasına göre sıralar:
const sayilar = [21.5, 19.75, 100, 3]; console.log([...sayilar].sort()); console.log([...sayilar].sort((a, b) => a - b)); console.log(sayilar.toSorted((a, b) => b - a)); console.log(sayilar);
[ 100, 19.75, 21.5, 3 ] [ 3, 19.75, 21.5, 100 ] [ 100, 21.5, 19.75, 3 ] [ 21.5, 19.75, 100, 3 ]
İlk satır sayısal olarak yanlıştır ama kural gereği doğrudur: "100" metni "3"
metninden önce gelir. Sayısal sıralama için karşılaştırma fonksiyonu zorunludur.
Fonksiyon negatif, sıfır veya pozitif döndürerek sırayı bildirir; a - b artan, b - a
azalan sıra verir.
Son iki satır ayrıca değiştiren–değiştirmeyen ayrımını gösteriyor: toSorted özgün
diziyi bozmadı. sort çağrıları kopya üzerinde yapıldığı için sayilar hiç değişmedi.
Dönüştürme Zincirleri
Ölçüm listesi üzerindeki işlerin çoğu birkaç yöntemin zincirlenmesiyle yazılır:
const kayitlar = [ { istasyon: "A1", sicaklik: 21.5 }, { istasyon: "A2", sicaklik: 19.75 }, { istasyon: "B1", sicaklik: 23 }, { istasyon: "B2", sicaklik: 18.25 }, ]; console.log(kayitlar.map((k) => k.sicaklik)); console.log(kayitlar.filter((k) => k.sicaklik > 20).map((k) => k.istasyon)); console.log(kayitlar.reduce((t, k) => t + k.sicaklik, 0)); console.log(kayitlar.find((k) => k.istasyon === "B1")); console.log(kayitlar.findIndex((k) => k.sicaklik > 22)); console.log(kayitlar.some((k) => k.sicaklik > 22), kayitlar.every((k) => k.sicaklik > 15));
[ 21.5, 19.75, 23, 18.25 ]
[ 'A1', 'B1' ]
82.5
{ istasyon: 'B1', sicaklik: 23 }
2
true true
Programlama Temelleri kursundaki eşleme, süzme ve indirgeme üçlüsü bunlardır. find ilk
eşleşen elemanı, findIndex dizinini verir; bulunamazsa sırasıyla undefined ve -1
döner. some ve every mantıksal değer üretir ve kısa devre yapar.
İndirgeme, birikeci bir nesne olduğunda tek geçişte birden çok özet üretir:
const kayitlar = [ { istasyon: "A1", sicaklik: 21.5 }, { istasyon: "A2", sicaklik: 19.75 }, { istasyon: "B1", sicaklik: 23 }, ]; const ozet = kayitlar.reduce( (birikec, kayit) => ({ adet: birikec.adet + 1, toplam: birikec.toplam + kayit.sicaklik, enYuksek: Math.max(birikec.enYuksek, kayit.sicaklik), }), { adet: 0, toplam: 0, enYuksek: -Infinity }, ); console.log(ozet); console.log("ortalama:", ozet.toplam / ozet.adet);
{ adet: 3, toplam: 64.25, enYuksek: 23 }
ortalama: 21.416666666666668
Başlangıç değeri isteğe bağlı görünür ama değildir:
try { console.log([].reduce((a, b) => a + b)); } catch (hata) { console.log(hata.name + ": " + hata.message); } console.log([].reduce((a, b) => a + b, 0));
TypeError: Reduce of empty array with no initial value 0
Başlangıç değeri verilmezse ilk eleman birikeç olur ve boş dizide böyle bir eleman yoktur. Kural: indirgeme her zaman başlangıç değeriyle yazılır.
İç içe listeler flat ve flatMap ile düzleştirilir:
const gruplar = [[21.5, 19.75], [23], [], [18.25]]; console.log(gruplar.flat()); console.log(gruplar.flatMap((g) => g.map((d) => d * 2))); console.log([1, [2, [3, [4]]]].flat(2));
[ 21.5, 19.75, 23, 18.25 ] [ 43, 39.5, 46, 36.5 ] [ 1, 2, 3, [ 4 ] ]
flat öntanımlı olarak yalnızca bir düzey açar; derinlik argümanla verilir. Son satırda
iki düzey açıldı, üçüncü düzey dizi olarak kaldı.
Özet
- Tek sayısal argümanlı dizi yapıcısı o uzunlukta boş dizi üretir; eleman için
Array.ofveya doğrudan yazım kullanılır. - Boşluklar
undefinedtaşıyan elemanlardan farklıdır ve eşleme yöntemleri tarafından atlanır;lengthalanına yazmak diziyi kırpar veya boşluk açar. - Aralık dışı dizin
undefinedverir;atnegatif dizin kabul eder;indexOfNaNbulamaz,includesbulur. - Yöntemler değiştiren ve değiştirmeyen olarak ikiye ayrılır; kopyalar sığdır.
- Karşılaştırma fonksiyonu verilmeyen sıralama metne çevirip sözlük sırası uygular.
- İndirgeme başlangıç değeriyle yazılır; verilmezse boş dizide hata üretir.
Sonraki Adım
Bu derste kayıtlar nesne olarak kullanıldı ama nesne sözdizimi tanımlanmadı. Sonraki ders nesneleri ele alacak: özellik erişiminin iki biçimi, kısaltmalı yazım, hesaplanmış anahtarlar, yapıbozum ve yayma. Ölçüm kayıtlarını istasyona göre gruplamak da orada yazılacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.