Takip et

JavaScript’te Dizileri Anlamak: Kapsamlı Bir Rehber

JavaScript’te Dizileri Anlamak: Kapsamlı Bir Rehber Giriş: Diziler Neden Bu Kadar Önemli? JavaScript, modern web geliştirmenin temel taşlarınd

JavaScript’te Dizileri Anlamak: Kapsamlı Bir Rehber

Giriş: Diziler Neden Bu Kadar Önemli?

JavaScript, modern web geliştirmenin temel taşlarından biridir ve bu dilin sunduğu en güçlü ve esnek veri yapılarından biri de dizilerdir (Arrays). Diziler, birden fazla değeri tek bir değişken altında düzenli bir şekilde saklamamızı sağlayan, sıralı koleksiyonlardır. İster bir kullanıcı listesi, ister bir ürün kataloğu, isterse bir dizi sayısal veri olsun, JavaScript dizileri bu tür veri kümelerini etkin bir şekilde yönetmek için vazgeçilmez bir araçtır.

Bir dizi, elemanlarına bir indeks (sıra numarası) aracılığıyla erişilebilen, sıfır tabanlı bir veri yapısıdır. Yani, bir dizinin ilk elemanı 0. indekste, ikinci elemanı 1. indekste yer alır ve bu böyle devam eder. JavaScript dizileri, diğer bazı dillerdeki dizilerin aksine, farklı veri tiplerini aynı anda barındırabilir. Bir dizide hem sayılar, hem metinler, hem boolean değerler, hem de nesneler bulunabilir. Bu esneklik, JavaScript’i dinamik ve çeşitli veri yapılarıyla çalışmak için oldukça güçlü kılar.

Bu makalede, JavaScript dizilerinin temelden ileri seviyeye kadar tüm yönlerini ele alacağız. Dizi oluşturma yöntemlerinden elemanlara erişime, dizileri manipüle etme metotlarından gelişmiş yineleme tekniklerine, performans ipuçlarından en iyi uygulamalara kadar geniş bir yelpazede bilgi sunarak, dizileri tam anlamıyla anlamanızı ve projelerinizde etkin bir şekilde kullanmanızı sağlayacağız.

JavaScript Dizilerinin Temelleri

Diziler, programlamada veri koleksiyonlarını düzenlemenin en temel yollarından biridir. JavaScript’te bir dizi oluşturmak ve elemanlarına erişmek oldukça kolaydır.

Dizi Oluşturma Yöntemleri

JavaScript’te dizi oluşturmanın birkaç farklı yolu vardır. En yaygın ve önerilen yöntem dizi literalidir.

Dizi Literali []

Dizi literalini kullanarak bir dizi oluşturmak, en basit ve en yaygın yöntemdir. Köşeli parantezler [] arasına, virgülle ayrılmış elemanları yazarak bir dizi oluşturulur.

const meyveler = ["Elma", "Muz", "Portakal"];
const sayilar = [1, 2, 3, 4, 5];
const karisikDizi = ["Merhaba", 123, true, { ad: "Ahmet" }];

console.log(meyveler);    // ["Elma", "Muz", "Portakal"]
console.log(sayilar);     // [1, 2, 3, 4, 5]
console.log(karisikDizi); // ["Merhaba", 123, true, { ad: "Ahmet" }]

Boş bir dizi oluşturmak için sadece [] kullanabilirsiniz:

const bosDizi = [];
console.log(bosDizi); // []
new Array() Yapıcı Fonksiyonu

Dizileri Array yapıcı fonksiyonunu kullanarak da oluşturabilirsiniz. Ancak, bu yöntem genellikle dizi literalinden daha az tercih edilir çünkü bazı durumlarda kafa karıştırıcı olabilir.

Tek bir sayısal argümanla çağrıldığında, bu sayı dizinin eleman sayısı olarak yorumlanır ve dizi boş elemanlarla (empty slots) doldurulur:

const besElemanliDizi = new Array(5);
console.log(besElemanliDizi); // [empty × 5]
console.log(besElemanliDizi.length); // 5

Birden fazla argümanla veya tek bir sayısal olmayan argümanla çağrıldığında, argümanlar dizinin elemanları olarak kabul edilir:

const harfler = new Array("a", "b", "c");
console.log(harfler); // ["a", "b", "c"]

const tekElemanliDizi = new Array("Merhaba");
console.log(tekElemanliDizi); // ["Merhaba"]

new Array() kullanımı, özellikle tek bir sayısal argüman verildiğinde, beklenmedik davranışlara yol açabileceği için genellikle dizi literalinin kullanılması önerilir.

Array.of() Metodu

Array.of() metodu, new Array() yapıcı fonksiyonunun tek sayısal argümanla ilgili kafa karışıklığını giderir. Bu metot, kendisine verilen tüm argümanları eleman olarak içeren yeni bir dizi oluşturur.

const diziOf = Array.of(1, 2, 3, "dört");
console.log(diziOf); // [1, 2, 3, "dört"]

const tekSayiOf = Array.of(7);
console.log(tekSayiOf); // [7]

Array.of() her zaman argümanları eleman olarak kabul eder, asla dizinin uzunluğu olarak değil.

Array.from() Metodu

Array.from() metodu, dizi benzeri (array-like) veya yinelenebilir (iterable) bir nesneden yeni bir Array örneği oluşturur. Bu, özellikle DOM eleman listeleri (NodeList) veya arguments nesnesi gibi dizi benzeri yapıları gerçek dizilere dönüştürmek için kullanışlıdır.

const metin = "Merhaba";
const harflerDizisi = Array.from(metin);
console.log(harflerDizisi); // ["M", "e", "r", "h", "a", "b", "a"]

// Dizi benzeri bir nesneden
const diziBenzeri = { 0: 'a', 1: 'b', 2: 'c', length: 3 };
const gercekDizi = Array.from(diziBenzeri);
console.log(gercekDizi); // ["a", "b", "c"]

// İkinci bir argüman olarak bir map fonksiyonu da alabilir
const sayilarKare = Array.from([1, 2, 3], x => x * x);
console.log(sayilarKare); // [1, 4, 9]

Array.from() güçlü bir metottur ve özellikle fonksiyonel programlama paradigmalarında veri dönüşümleri için sıkça kullanılır.

Dizi Elemanlarına Erişim ve Uzunluk

Dizi elemanlarına erişim, indeksleme operatörü [] kullanılarak yapılır. Diziler sıfır tabanlı indekslendiği için, ilk elemanın indeksi 0, ikincinin 1 vb. şeklindedir.

const renkler = ["Kırmızı", "Yeşil", "Mavi"];

console.log(renkler[0]); // "Kırmızı"
console.log(renkler[1]); // "Yeşil"
console.log(renkler[2]); // "Mavi"
console.log(renkler[3]); // undefined (3. indeksde eleman yok)
length Özelliği

Bir dizinin kaç eleman içerdiğini öğrenmek için length özelliğini kullanırız. Bu özellik, dizideki eleman sayısını döndürür.

const urunler = ["Laptop", "Mouse", "Klavye"];
console.log(urunler.length); // 3

urunler[3] = "Monitör"; // Yeni eleman ekleme
console.log(urunler.length); // 4

urunler.length = 2; // Diziyi kısaltma (fazla elemanlar silinir)
console.log(urunler); // ["Laptop", "Mouse"]
console.log(urunler.length); // 2

length özelliğini manuel olarak değiştirmek, diziyi kısaltmak veya boş elemanlar eklemek için kullanılabilir, ancak bu genellikle doğrudan eleman ekleme/çıkarma metotları kadar yaygın değildir.

Dizileri Değiştirme ve Manipüle Etme

JavaScript dizileri dinamiktir; yani oluşturulduktan sonra elemanları eklenebilir, çıkarılabilir veya güncellenebilir. Bu, dizileri esnek veri yapıları yapar.

Eleman Ekleme ve Çıkarma

JavaScript, dizinin başına veya sonuna eleman eklemek/çıkarmak için özel metotlar sunar.

push() ve pop()

* push(): Dizinin sonuna bir veya daha fazla eleman ekler ve dizinin yeni uzunluğunu döndürür.
* pop(): Dizinin son elemanını çıkarır ve çıkarılan elemanı döndürür. Dizi boşsa undefined döndürür.

const sehirler = ["Ankara", "İzmir"];

sehirler.push("İstanbul");
console.log(sehirler); // ["Ankara", "İzmir", "İstanbul"]

sehirler.push("Bursa", "Adana");
console.log(sehirler); // ["Ankara", "İzmir", "İstanbul", "Bursa", "Adana"]

const cikarilanSehir = sehirler.pop();
console.log(cikarilanSehir); // "Adana"
console.log(sehirler);       // ["Ankara", "İzmir", "İstanbul", "Bursa"]
unshift() ve shift()

* unshift(): Dizinin başına bir veya daha fazla eleman ekler ve dizinin yeni uzunluğunu döndürür. Bu işlem, mevcut elemanların indekslerini değiştirdiği için push()‘a göre daha yavaş olabilir.
* shift(): Dizinin ilk elemanını çıkarır ve çıkarılan elemanı döndürür. Dizi boşsa undefined döndürür. Bu işlem de pop()‘a göre daha yavaş olabilir.

const sayilar = [2, 3];

sayilar.unshift(1);
console.log(sayilar); // [1, 2, 3]

sayilar.unshift(-1, 0);
console.log(sayilar); // [-1, 0, 1, 2, 3]

const cikarilanSayi = sayilar.shift();
console.log(cikarilanSayi); // -1
console.log(sayilar);       // [0, 1, 2, 3]
splice(): Çok Yönlü Manipülasyon

splice() metodu, dizileri değiştirmek için en güçlü ve esnek araçlardan biridir. Mevcut elemanları kaldırabilir, yeni elemanlar ekleyebilir veya her ikisini birden yapabilir.

Sözdizimi: array.splice(startIndex, deleteCount, item1, item2, ...)

* startIndex: Değişikliğin başlayacağı indeks.
* deleteCount: startIndex‘ten itibaren kaç elemanın silineceği. 0 olması durumunda eleman silinmez.
* item1, item2, ...: startIndex‘ten itibaren eklenecek elemanlar.

splice() metodu, silinen elemanları içeren bir dizi döndürür.

const meyveler = ["Elma", "Muz", "Portakal", "Çilek", "Kivi"];

// Eleman silme
const silinenMeyveler = meyveler.splice(1, 2); // 1. indeksten itibaren 2 eleman sil
console.log(silinenMeyveler); // ["Muz", "Portakal"]
console.log(meyveler);        // ["Elma", "Çilek", "Kivi"]

// Eleman ekleme
meyveler.splice(1, 0, "Armut", "Üzüm"); // 1. indekse eleman ekle, hiç silme
console.log(meyveler); // ["Elma", "Armut", "Üzüm", "Çilek", "Kivi"]

// Eleman değiştirme (silme ve ekleme)
meyveler.splice(2, 1, "Ananas"); // 2. indeksteki elemanı sil ve "Ananas" ekle
console.log(meyveler); // ["Elma", "Armut", "Ananas", "Çilek", "Kivi"]

Elemanları Güncelleme

Mevcut bir dizinin elemanını güncellemek için ilgili indeksi kullanarak doğrudan atama yapabilirsiniz.

const puanlar = [85, 92, 78, 95];

puanlar[2] = 88; // 2. indeksteki elemanı güncelle
console.log(puanlar); // [85, 92, 88, 95]

puanlar[4] = 100; // Olmayan bir indekse atama yapmak diziyi genişletir
console.log(puanlar); // [85, 92, 88, 95, 100]

Eğer var olmayan bir indekse değer atarsanız, dizi otomatik olarak o indekse kadar genişler ve aradaki boşluklar “empty” (seyrek dizi) olarak işaretlenir.

Diziler Üzerinde Yineleme (Iteration)

Dizilerdeki her bir eleman üzerinde işlem yapmak, veri işleme süreçlerinin temelini oluşturur. JavaScript, diziler üzerinde yineleme yapmak için çeşitli metotlar sunar.

Geleneksel Döngüler

for Döngüsü

Geleneksel for döngüsü, diziler üzerinde yineleme yapmanın en temel yoludur. İndeks kontrolü sağlar.

const isimler = ["Ali", "Ayşe", "Mehmet"];

for (let i = 0; i < isimler.length; i++) {
    console.log(Merhaba, ${isimler[i]});
}
// Çıktı:
// Merhaba, Ali
// Merhaba, Ayşe
// Merhaba, Mehmet
for...of Döngüsü

for...of döngüsü, ES6 ile tanıtılan ve yinelenebilir nesneler (diziler, stringler, Map, Set vb.) üzerinde doğrudan eleman değerleri üzerinde yineleme yapmayı sağlayan daha modern ve okunabilir bir yoldur.

const urunler = ["TV", "Buzdolabı", "Çamaşır Makinesi"];

for (const urun of urunler) {
    console.log(Ürün: ${urun});
}
// Çıktı:
// Ürün: TV
// Ürün: Buzdolabı
// Ürün: Çamaşır Makinesi

for...in döngüsü de vardır ancak bu, diziler için değil, nesne özelliklerini yinelemek için tasarlanmıştır. Dizilerde kullanıldığında beklenmedik davranışlara yol açabilir (örneğin, prototip zincirindeki özellikleri de listeleyebilir). Bu nedenle diziler için for...in kullanmaktan kaçınılmalıdır.

Modern Yineleme Metotları

JavaScript’in modern sürümleri, diziler üzerinde daha işlevsel ve deklaratif bir yaklaşımla yineleme yapmamızı sağlayan yüksek dereceli (higher-order) metotlar sunar.

forEach()

forEach() metodu, dizideki her bir eleman için bir geri çağırma (callback) fonksiyonu çalıştırır. Yeni bir dizi döndürmez, sadece yan etki (side effect) oluşturmak için kullanılır.

const puanlar = [80, 90, 75];

puanlar.forEach(function(puan, index) {
    console.log(${index + 1}. öğrencinin puanı: ${puan});
});
// Çıktı:
// 1. öğrencinin puanı: 80
// 2. öğrencinin puanı: 90
// 3. öğrencinin puanı: 75

Arrow fonksiyonlarla daha kısa yazılabilir:

puanlar.forEach(puan => console.log(Puan: ${puan}));
map(): Yeni Dizi Oluşturma

map() metodu, dizideki her eleman için bir geri çağırma fonksiyonu çalıştırır ve bu fonksiyonun döndürdüğü değerlerle yeni bir dizi oluşturur. Orijinal dizi değişmez.

const sayilar = [1, 2, 3, 4];
const kareleri = sayilar.map(sayi => sayi * sayi);

console.log(kareleri); // [1, 4, 9, 16]
console.log(sayilar);  // [1, 2, 3, 4] (orijinal dizi değişmedi)

map() veri dönüşümleri için çok güçlü bir araçtır.

filter(): Koşula Göre Eleme

filter() metodu, dizideki her eleman için bir geri çağırma fonksiyonu çalıştırır ve bu fonksiyon true döndüren elemanlardan oluşan yeni bir dizi oluşturur. Orijinal dizi değişmez.

const yaslar = [15, 22, 18, 30, 16, 25];
const yetiskinYaslar = yaslar.filter(yas => yas >= 18);

console.log(yetiskinYaslar); // [22, 18, 30, 25]
console.log(yaslar);         // [15, 22, 18, 30, 16, 25] (orijinal dizi değişmedi)
reduce(): Tek Bir Değere İndirgeme

reduce() metodu, dizideki her eleman için bir geri çağırma fonksiyonu (reducer) çalıştırır ve diziyi tek bir değere (sayı, nesne, string vb.) indirger.

Sözdizimi: array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)

* accumulator: Geri çağırma fonksiyonunun önceki çağrısından dönen değerdir (veya initialValue).
* currentValue: Şu an işlenen dizi elemanı.
* initialValue: İsteğe bağlıdır. accumulator‘ın ilk değeri. Belirtilmezse, dizinin ilk elemanı kullanılır ve currentValue dizinin ikinci elemanından başlar.

const sayilar = [1, 2, 3, 4, 5];

// Toplamı bulma
const toplam = sayilar.reduce((acc, current) => acc + current, 0);
console.log(toplam); // 15

// Maksimum değeri bulma
const maxDeger = sayilar.reduce((max, current) => (current > max ? current : max), sayilar[0]);
console.log(maxDeger); // 5

// Düz bir nesneye dönüştürme
const urunler = [{ id: 1, ad: "Kalem" }, { id: 2, ad: "Defter" }];
const urunObjesi = urunler.reduce((obj, urun) => {
    obj[urun.id] = urun.ad;
    return obj;
}, {});
console.log(urunObjesi); // { '1': 'Kalem', '2': 'Defter' }

reduce(), dizileri karmaşık veri yapılarına dönüştürmek veya tek bir özet değer elde etmek için inanılmaz derecede esnek bir metottur.

every() ve some(): Koşul Kontrolü

* every(): Dizideki tüm elemanların belirtilen bir koşulu sağlayıp sağlamadığını kontrol eder. Tüm elemanlar koşulu sağlarsa true, aksi takdirde false döndürür.
* some(): Dizideki en az bir elemanın belirtilen bir koşulu sağlayıp sağlamadığını kontrol eder. En az bir eleman koşulu sağlarsa true, aksi takdirde false döndürür.

const notlar = [80, 85, 90, 75];

const hepsiGecti = notlar.every(not => not >= 70);
console.log(hepsiGecti); // true (tüm notlar 70'ten büyük veya eşit)

const enAzBiriYuksek = notlar.some(not => not > 90);
console.log(enAzBiriYuksek); // false (hiçbir not 90'dan büyük değil)

const enAzBiriGecti = notlar.some(not => not >= 70);
console.log(enAzBiriGecti); // true (en az biri 70'ten büyük veya eşit)

Yaygın Dizi Metotları ve Kullanımları

JavaScript dizileri, veri manipülasyonu için zengin bir dizi metot seti sunar. Bu metotlar, dizileri birleştirmekten, eleman aramaya, sıralamaya kadar birçok işlemi kolaylaştırır.

Birleştirme ve Kopyalama

concat()

concat() metodu, mevcut bir diziyi veya dizileri başka dizilerle veya değerlerle birleştirerek yeni bir dizi oluşturur. Orijinal diziler değişmez.

const dizi1 = [1, 2];
const dizi2 = [3, 4];
const dizi3 = [5, 6];

const birlesikDizi = dizi1.concat(dizi2, dizi3);
console.log(birlesikDizi); // [1, 2, 3, 4, 5, 6]
console.log(dizi1);        // [1, 2] (orijinal dizi değişmedi)

const diziVeDegerler = dizi1.concat(3, 4, "beş");
console.log(diziVeDegerler); // [1, 2, 3, 4, "beş"]
slice()

slice() metodu, bir dizinin belirli bir kısmını seçerek yeni bir dizi döndürür. Orijinal dizi değişmez.

Sözdizimi: array.slice(startIndex, endIndex)

* startIndex: Seçimin başlayacağı indeks. İsteğe bağlı. Belirtilmezse 0’dan başlar. Negatif bir sayı ise dizinin sonundan başlar.
* endIndex: Seçimin biteceği indeks (bu indeks dahil değildir). İsteğe bağlı. Belirtilmezse dizinin sonuna kadar gider. Negatif bir sayı ise dizinin sonundan başlar.

const renkler = ["Kırmızı", "Yeşil", "Mavi", "Sarı", "Mor"];

const araRenkler = renkler.slice(1, 4); // 1. indeksten 4. indekse kadar (4 dahil değil)
console.log(araRenkler); // ["Yeşil", "Mavi", "Sarı"]

const sonIki = renkler.slice(-2); // Sondan 2 eleman
console.log(sonIki); // ["Sarı", "Mor"]

const tumDiziKopya = renkler.slice(); // Dizinin sığ bir kopyasını oluşturur
console.log(tumDiziKopya); // ["Kırmızı", "Yeşil", "Mavi", "Sarı", "Mor"]
Spread Operatörü (...)

Spread operatörü (...), ES6 ile gelen ve bir dizinin elemanlarını ayrı ayrı “yaymak” için kullanılan güçlü bir operatördür. Dizi kopyalama ve birleştirme işlemlerinde concat() ve slice() yerine modern bir alternatif sunar.

const arr1 = [1, 2];
const arr2 = [3, 4];

// Dizileri birleştirme
const birlesik = [...arr1, ...arr2, 5, 6];
console.log(birlesik); // [1, 2, 3, 4, 5, 6]

// Diziyi kopyalama (sığ kopya)
const kopyaArr1 = [...arr1];
console.log(kopyaArr1); // [1, 2]

Arama ve Bulma

indexOf() ve lastIndexOf()

* indexOf(): Belirtilen bir elemanın dizideki ilk geçtiği indeksini döndürür. Bulunamazsa -1 döndürür.
* lastIndexOf(): Belirtilen bir elemanın dizideki son geçtiği indeksini döndürür. Bulunamazsa -1 döndürür.

const meyveler = ["Elma", "Muz", "Elma", "Portakal"];

console.log(meyveler.indexOf("Elma"));    // 0
console.log(meyveler.lastIndexOf("Elma")); // 2
console.log(meyveler.indexOf("Kivi"));    // -1
includes()

includes() metodu, bir dizinin belirli bir elemanı içerip içermediğini kontrol eder ve true veya false döndürür. ES7 ile gelmiştir ve indexOf() !== -1 kontrolüne daha okunabilir bir alternatif sunar.

const renkler = ["Kırmızı", "Yeşil", "Mavi"];

console.log(renkler.includes("Yeşil")); // true
console.log(renkler.includes("Sarı"));  // false
find() ve findIndex()

* find(): Dizideki belirtilen bir koşulu sağlayan ilk elemanın değerini döndürür. Hiçbir eleman koşulu sağlamazsa undefined döndürür.
* findIndex(): Dizideki belirtilen bir koşulu sağlayan ilk elemanın indeksini döndürür. Hiçbir eleman koşulu sağlamazsa -1 döndürür.

const kisiler = [
    { id: 1, ad: "Ali" },
    { id: 2, ad: "Ayşe" },
    { id: 3, ad: "Ali" }
];

const ali = kisiler.find(kisi => kisi.ad === "Ali");
console.log(ali); // { id: 1, ad: "Ali" }

const ayseIndex = kisiler.findIndex(kisi => kisi.ad === "Ayşe");
console.log(ayseIndex); // 1

const olmayanKisi = kisiler.find(kisi => kisi.ad === "Can");
console.log(olmayanKisi); // undefined

Sıralama ve Ters Çevirme

sort()

sort() metodu, dizinin elemanlarını yerinde (in-place) sıralar ve sıralanmış diziyi döndürür. Varsayılan olarak elemanları string olarak kabul eder ve Unicode karakter kodlarına göre sıralar. Bu, sayılarla çalışırken beklenmedik sonuçlar verebilir.

const harfler = ["c", "a", "b"];
harfler.sort();
console.log(harfler); // ["a", "b", "c"]

const sayilar = [10, 2, 20, 1];
sayilar.sort();
console.log(sayilar); // [1, 10, 2, 20] - Yanlış sıralama!

// Sayıları doğru sıralamak için bir karşılaştırma fonksiyonu gerekir
sayilar.sort((a, b) => a - b); // Küçükten büyüğe
console.log(sayilar); // [1, 2, 10, 20]

sayilar.sort((a, b) => b - a); // Büyükten küçüğe
console.log(sayilar); // [20, 10, 2, 1]
reverse()

reverse() metodu, dizinin elemanlarının sırasını yerinde (in-place) tersine çevirir ve tersine çevrilmiş diziyi döndürür.

const sehirler = ["Ankara", "İzmir", "İstanbul"];
sehirler.reverse();
console.log(sehirler); // ["İstanbul", "İzmir", "Ankara"]

Diziyi Metne Çevirme

join()

join() metodu, bir dizinin tüm elemanlarını birleştirerek bir string oluşturur. Elemanlar arasına isteğe bağlı bir ayırıcı (separator) string eklenebilir. Ayırıcı belirtilmezse varsayılan olarak virgül (,) kullanılır.

const kelimeler = ["Merhaba", "Dünya", "!"];
const cumle = kelimeler.join(" ");
console.log(cumle); // "Merhaba Dünya !"

const sayilarStr = [1, 2, 3].join("-");
console.log(sayilarStr); // "1-2-3"

İç İçe Dizileri Düzleştirme

flat() ve flatMap()

* flat(): İç içe geçmiş dizileri belirtilen bir derinlik seviyesine kadar düzleştirir (flatten). Varsayılan derinlik 1’dir.
* flatMap(): map() metodu gibi önce her eleman için bir fonksiyon çağırır, ardından sonuçları tek bir yeni diziye düzleştirir (derinlik 1).

const icIceDizi = [1, [2, 3], [4, [5, 6]]];

const duzDizi1 = icIceDizi.flat();
console.log(duzDizi1); // [1, 2, 3, 4, [5, 6]] (varsayılan derinlik 1)

const tamDuzDizi = icIceDizi.flat(2); // 2 derinliğe kadar düzleştir
console.log(tamDuzDizi); // [1, 2, 3, 4, 5, 6]

const mapVeDuzlestir = [1, 2, 3].flatMap(x => [x, x * 2]);
console.log(mapVeDuzlestir); // [1, 2, 2, 4, 3, 6]

Dizinin Dizi Olup Olmadığını Kontrol Etme

Array.isArray()

Array.isArray() metodu, verilen değerin bir dizi olup olmadığını kontrol eder ve true veya false döndürür. Bu, typeof operatörünün dizi için “object” döndürmesi nedeniyle önemlidir.

const arr = [1, 2, 3];
const obj = { a: 1 };
const str = "hello";

console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
console.log(Array.isArray(str)); // false

İleri Dizi Kavramları

JavaScript dizileriyle çalışırken verimliliği ve kod okunabilirliğini artıran bazı ileri düzey kavramlar da bulunmaktadır.

Spread Operatörü ve Kopyalama

Daha önce de bahsettiğimiz spread operatörü (...), dizileri kopyalamak için de harika bir yoldur. slice() metoduna benzer şekilde sığ (shallow) bir kopya oluşturur. Bu, özellikle orijinal diziyi değiştirmek istemediğiniz durumlarda kullanışlıdır.

const orijinalDizi = [1, 2, 3];
const kopyaDizi = [...orijinalDizi];

console.log(kopyaDizi); // [1, 2, 3]
console.log(kopyaDizi === orijinalDizi); // false (farklı referanslar)

kopyaDizi.push(4);
console.log(orijinalDizi); // [1, 2, 3] (orijinal dizi değişmedi)
console.log(kopyaDizi);    // [1, 2, 3, 4]

Nesneler içeren dizilerde spread operatörü sığ kopyalama yaptığından, iç içe nesnelerin referansları aynı kalır. Derin kopya (deep copy) için farklı yöntemler (örneğin JSON.parse(JSON.stringify(array)) veya özel kopyalama kütüphaneleri) kullanmak gerekebilir.

Dizi Ayrıştırma (Destructuring Assignment)

Dizi ayrıştırma, ES6 ile gelen bir özelliktir ve dizi elemanlarını ayrı değişkenlere atamanın daha kısa ve okunaklı bir yolunu sunar.

const renkler = ["Kırmızı", "Yeşil", "Mavi"];

// Geleneksel yöntem
// const ilkRenk = renkler[0];
// const ikinciRenk = renkler[1];

// Dizi ayrıştırma
const [ilkRenk, ikinciRenk, ucuncuRenk] = renkler;
console.log(ilkRenk);    // "Kırmızı"
console.log(ikinciRenk); // "Yeşil"

// Kalan elemanları toplama (rest parameter)
const [baslangic, ...kalanlar] = [1, 2, 3, 4, 5];
console.log(baslangic); // 1
console.log(kalanlar);  // [2, 3, 4, 5]

Bu özellik, özellikle fonksiyonlardan birden fazla değer döndürüldüğünde veya dizi elemanlarına hızlıca erişmek gerektiğinde çok kullanışlıdır.

Seyrek Diziler (Sparse Arrays)

JavaScript dizileri seyrek olabilir, yani tüm indekslerde eleman bulunmayabilir. Bir dizinin length özelliği, son elemanın indeksinden daha büyük olabilir. Bu durumda, aradaki indeksler “empty” (boş yuvalar) olarak işaretlenir.

const seyrekDizi = [1, , 3]; // 1. indeks boş
console.log(seyrekDizi);         // [1, empty, 3]
console.log(seyrekDizi.length);  // 3
console.log(seyrekDizi[1]);      // undefined

seyrekDizi[5] = 6; // Dizi otomatik olarak genişler
console.log(seyrekDizi);         // [1, empty, 3, empty × 2, 6]
console.log(seyrekDizi.length);  // 6

Seyrek dizilerle çalışırken dikkatli olmak gerekir, çünkü bazı yineleme metotları (örneğin forEach, map, filter) boş yuvaları atlayabilirken, for döngüsü undefined değerler döndürebilir.

Dizi Benzeri Nesneler (Array-like Objects)

JavaScript’te bazı nesneler dizilere benzer özellikler gösterir: length özelliğine sahiptirler ve elemanlarına indekslerle erişilebilirler. Ancak, bu nesneler push(), pop(), forEach() gibi dizi metotlarına sahip değildirler. Örnekler:

* arguments nesnesi (fonksiyon içinde)
* DOM NodeList (örneğin document.querySelectorAll() tarafından döndürülen)
* HTMLCollection

Bu tür nesneleri gerçek bir diziye dönüştürmek için Array.from() veya spread operatörü kullanılabilir:

function toplaSayilar() {
    // arguments bir dizi benzeri nesnedir
    const argsDizisi = Array.from(arguments);
    console.log(argsDizisi); // Gerçek bir dizi

    const toplam = argsDizisi.reduce((acc, val) => acc + val, 0);
    return toplam;
}

console.log(toplaSayilar(1, 2, 3)); // 6

// Veya spread operatörü ile
function toplaSayilarSpread(...args) { // args artık gerçek bir dizi
    return args.reduce((acc, val) => acc + val, 0);
}
console.log(toplaSayilarSpread(4, 5, 6)); // 15

Dizilerde Değişmezlik (Immutability)

Değişmezlik (immutability), bir veri yapısı oluşturulduktan sonra değiştirilemeyeceği anlamına gelir. JavaScript dizileri varsayılan olarak değişebilir (mutable) yapıdadır, yani push(), pop(), splice(), sort(), reverse() gibi metotlar orijinal diziyi değiştirir.

Fonksiyonel programlama paradigmalarında ve React gibi modern kütüphanelerde değişmezlik önemli bir kavramdır. Değişmez verilerle çalışmak, kodun daha öngörülebilir olmasını, hataların azalmasını ve paralel işlemleri kolaylaştırır.

Değişmez bir şekilde dizileri manipüle etmek için, orijinal diziyi değiştirmeyen metotları kullanmalı veya yeni bir dizi oluşturmalısınız:

* Ekleme: concat() veya spread operatörü (...) kullanın.

const orijinal = [1, 2];
    const yeniDizi = [...orijinal, 3]; // [1, 2, 3]

* Silme: filter() veya slice() kullanın.

const orijinal = [1, 2, 3];
    const yeniDizi = orijinal.filter(item => item !== 2); // [1, 3]
    const yeniDizi2 = [...orijinal.slice(0, 1), ...orijinal.slice(2)]; // [1, 3]

* Güncelleme: map() veya spread operatörü ile yeni bir dizi oluşturun.

const orijinal = [{ id: 1, ad: "A" }, { id: 2, ad: "B" }];
    const yeniDizi = orijinal.map(item =>
        item.id === 2 ? { ...item, ad: "C" } : item
    );
    // [{ id: 1, ad: "A" }, { id: 2, ad: "C" }]

Bu yaklaşımlar, orijinal dizinin değişmeden kalmasını sağlar ve bu da hata ayıklamayı ve uygulamanın durum yönetimini kolaylaştırır.

Performans İpuçları ve En İyi Uygulamalar

Dizilerle çalışırken performans ve kod kalitesi için bazı ipuçları ve en iyi uygulamalar şunlardır:

Doğru Metodu Seçmek

Her dizi metodu farklı bir amaca hizmet eder ve farklı performans özelliklerine sahiptir.

* Sadece yineleme için: forEach() veya for...of kullanın.
* Yeni dizi oluşturarak dönüştürme: map() kullanın.
* Elemanları filtreleme: filter() kullanın.
* Tek bir değer elde etme: reduce() kullanın.
* Dizinin başına eleman ekleme/çıkarma: unshift() ve shift() yerine, diziyi tersine çevirip push()/pop() kullanmak veya yeni bir dizi oluşturmak daha performanslı olabilir, çünkü unshift/shift tüm elemanların indekslerini değiştirmeyi gerektirir.
* Dizi kopyalama/birleştirme: Spread operatörü (...) veya slice()/concat() kullanın. Spread operatörü genellikle daha okunabilirdir.

Büyük Dizilerle Çalışırken

Çok büyük dizilerle çalışırken performans kritik hale gelebilir.

* Gereksiz yinelemelerden kaçının: Bir işlemi birden fazla adımda yapmak yerine tek bir reduce() çağrısı ile birleştirmek bazen daha verimli olabilir.
* Değişmezliği göz önünde bulundurun: Büyük dizilerde sık sık yeni diziler oluşturmak bellek ve CPU maliyetini artırabilir. Duruma göre değişebilir (mutable) operasyonlar kullanmak gerekebilir, ancak bunun yan etkilerini iyi yönetmelisiniz.
* for döngüsünün hızı: En temel for döngüsü, bazı durumlarda diğer modern metotlardan daha hızlı olabilir, çünkü daha az fonksiyon çağrısı ve overhead içerir. Ancak çoğu modern uygulamada okunabilirlik ve sürdürülebilirlik için map, filter gibi metotlar tercih edilir. Performans darboğazı olmadığı sürece bu metotları kullanmak genellikle iyi bir uygulamadır.

const Kullanımı

Bir dizinin referansının değişmesini istemiyorsanız, diziyi const ile tanımlayın. Bu, dizinin kendisini değiştirmeyi (eleman ekleme/çıkarma) engellemez, ancak dizi değişkenine başka bir dizi atamanızı engeller.

const sayilar = [1, 2, 3];
sayilar.push(4);      // Geçerli, dizi içeriği değişti
console.log(sayilar); // [1, 2, 3, 4]

// sayilar = [5, 6]; // Hata: Assignment to constant variable.

Mutable vs. Immutable Operasyonları Anlamak

Hangi dizi metodunun orijinal diziyi değiştirdiğini (mutable) ve hangisinin yeni bir dizi döndürdüğünü (immutable) bilmek çok önemlidir.

* Mutable: push, pop, shift, unshift, splice, sort, reverse
* Immutable: concat, slice, map, filter, reduce, find, findIndex, includes, join, flat, flatMap (ve spread operatörü)

Duruma göre doğru metodu seçmek, beklenmedik yan etkileri önler ve kodunuzu daha güvenilir hale getirir.

Sonuç

JavaScript dizileri, modern uygulama geliştirmede veri yönetimi için temel ve güçlü bir araçtır. Dizi oluşturmanın farklı yollarından, elemanlara erişime, dizileri manipüle etme metotlarından gelişmiş yineleme tekniklerine kadar geniş bir yelpazede yetenek sunarlar. map, filter, reduce gibi modern metotlar, kodunuzu daha deklaratif, okunabilir ve bakımı kolay hale getirirken, splice gibi metotlar size detaylı kontrol sağlar.

Spread operatörü ve dizi ayrıştırma gibi ES6+ özellikleri, dizilerle çalışmayı daha keyifli ve verimli kılar. Değişmezlik prensiplerini anlamak ve uygulamak, özellikle büyük ve karmaşık uygulamalarda hataları azaltmaya yardımcı olur.

Bu makalede ele alınan kavramları ve metotları ustalıkla kullanarak, JavaScript projelerinizde veri koleksiyonlarını etkin bir şekilde yönetebilir, daha temiz, daha işlevsel ve daha performanslı kodlar yazabilirsiniz. Dizilerle pratik yapmaya devam edin, farklı senaryolarda hangi metodun en uygun olduğunu deneyimleyerek öğrenin ve JavaScript’in bu temel yapı taşının tüm potansiyelini keşfedin.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.