İçeriğe geç
academia.sh

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.of veya doğrudan yazım kullanılır.
  • Boşluklar undefined taşıyan elemanlardan farklıdır ve eşleme yöntemleri tarafından atlanır; length alanına yazmak diziyi kırpar veya boşluk açar.
  • Aralık dışı dizin undefined verir; at negatif dizin kabul eder; indexOf NaN bulamaz, includes bulur.
  • 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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat