
JavaScript'te diziler ve nesnelerle çalışırken map, filter ve reduce gibi fonksiyonel yöntemler ile Object.assign ve spread (...) operatörü sık kullanılır. Bu yöntemler kodu daha okunabilir, test edilebilir ve sürdürülebilir kılmak için uygundur. Aşağıdaki rehber temel kavramları, kısa örnekleri ve immutable (değişmez) yaklaşımları gösterir. Temel referanslar: Emre Demir — map/reduce/filter, 1Kodum — Spread operatörü, Tutkit — spread ve immutable ve Yazılım Bilişim — dizi fonksiyonları.
map, bir dizideki her öğeyi verilen dönüşüm fonksiyonuna tabi tutar ve yeni bir dizi döndürür. Orijinal dizi değişmez; bu nedenle immutable işlemler için uygundur. Eğer amacınız öğeleri yeni bir biçime çevirmekse map doğru tercihtir.
// Sayıları ikiyle çarpma
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8]
// Nesne dizisinden sadece isimleri almak
const users = [{id:1, name:'Ali'}, {id:2, name:'Veli'}];
const names = users.map(u => u.name);
console.log(names); // ['Ali', 'Veli']
map içinde saf (pure) fonksiyonlar kullanmak, test ve tekrar kullanım kolaylığı sağlar.
filter, dizi öğelerini bir koşula göre eler ve koşulu sağlayan öğelerle yeni bir dizi döndürür. Orijinal dizi değiştirilmez. Filtreleme, görünür veri setini kısıtlamak için uygundur.
// 10'dan büyük sayıları filtreleme
const nums = [4, 11, 7, 20];
const greaterThan10 = nums.filter(n => n > 10);
console.log(greaterThan10); // [11, 20]
// Tamamlanmış görevleri alma
const todos = [{id:1, done:true}, {id:2, done:false}];
const completed = todos.filter(t => t.done);
console.log(completed);
reduce, bir diziyi tek bir değere indirgemek için kullanılır. Toplam, çarpım, objeye dönüştürme veya gruplayıcı (group by) işlemleri için uygundur. reduce, başlangıç değeri (initialValue) ile dikkatli kullanılmalıdır.
// Sayıların toplamı
const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, n) => acc + n, 0);
console.log(sum); // 10
// Kategorilere göre gruplayarak bir nesne oluşturma
const items = [
{type: 'fruit', name:'apple'},
{type: 'veg', name:'carrot'},
{type: 'fruit', name:'banana'}
];
const grouped = items.reduce((acc, it) => {
(acc[it.type] = acc[it.type] || []).push(it);
return acc;
}, {});
console.log(grouped);
Gruplama ve birikim işlemlerinde reduce çok kuvvetlidir; fakat karmaşık mantığı küçük, okunabilir yardımcı fonksiyonlara bölmek genellikle daha sürdürülebilirdir.
Genelde veri iş akışları şu adımları takip eder: filtrele -> dönüştür -> biriktir. Bu zincir, küçük ve anlamlı adımlarla okunabilir kod sağlar.
// Örnek: Belirli kategorideki ürünlerin toplam fiyatı
const products = [
{category:'fruit', price: 2},
{category:'veg', price: 3},
{category:'fruit', price: 5}
];
const totalFruitPrice = products
.filter(p => p.category === 'fruit')
.map(p => p.price)
.reduce((sum, p) => sum + p, 0);
console.log(totalFruitPrice); // 7
Zincirleme işlemlerde erbabı kadar ara diziler oluşur; büyük veri setlerinde bellek ve performans etkilerini göz önünde bulundurun.
Nesne birleştirme ve kopyalama için iki sık kullanılan yöntem Object.assign ve spread operatörüdür. Her ikisi de yüzeysel (shallow) kopyalama yapar; iç içe (nested) nesneler için derin kopyalama düşünülmelidir. Detaylı örnekler ve kullanım açıklamaları için 1Kodum — Spread operatörü kaynağına bakabilirsiniz.
| Yöntem | Davranış |
|---|---|
| Object.assign(target, ...sources) | Kaynakların enumerable özelliklerini target'a kopyalar ve target'ı döndürür (target değişir). |
| { ...obj } | Yeni bir nesne oluşturur; kaynaklar sağdan sola doğru yazılırken sonuncu özellikler öncekinin üzerine yazar. |
// Güvenli birleştirme (target'ı değiştirmeden)
const a = {x:1};
const b = {y:2};
const merged1 = Object.assign({}, a, b);
const merged2 = {...a, ...b};
Önemli nokta: her iki yöntem de shallow copy yapar; iç nesneler referans olarak taşınır.
Immutable (değişmez) pattern, veri üzerinde doğrudan değişiklik yapmadan yeni kopyalar oluşturarak yan etkileri azaltır. Diziler için map, filter, concat veya spread; nesneler için spread veya Object.assign ile yeni kopyalar oluşturabilirsiniz. Daha karmaşık (nested) yapılar için derin kopyalama gerekebilir.
// Bir todo öğesini immutable şekilde güncelleme
const todos = [{id:1, done:false}, {id:2, done:false}];
const updated = todos.map(t => t.id === 2 ? {...t, done:true} : t);
console.log(updated);
Basit derin kopyalama için bazı durumlarda JSON.parse(JSON.stringify(obj)) kullanılabilir; ancak bu yöntem fonksiyonları, undefined değerleri veya tarih (Date) nesnelerini doğru kopyalamaz. Karmaşık durumlarda güvenilir bir yardımcı kütüphane veya ortamın sunduğu derin kopyalama aracı tercih edilmelidir.
Immutable yaklaşımlar kodun test edilebilirliğini ve hata ayıklamayı kolaylaştırır; bununla birlikte büyük veri setlerinde performans etkileri olabilir, dolayısıyla gereksinime göre uygun denge kurulmalıdır. Tutkit ve diğer kaynaklar immutable kullanımlarıyla ilgili pratik örnekler sunar (Tutkit).
Bu rehber fonksiyonel yöntemleri ve nesne birleştirmeyi pratik örneklerle gösterir; daha ayrıntılı kaynaklar ve açıklamalar için baştaki referanslara bakabilirsiniz: map/filter/reduce, spread operatörü, immutable örnekleri ve dizi fonksiyonları.
Yorumlar