ES6: Map ve Set

status
Published
date
Nov 21, 2018
slug
es6-map-and-set
Draft
tags
summary
Önceki bir kaç yazıda yaptığım gibi yine not alarak çalışacağım, hadi bakalım. 💃🏻
type
Post
Önceki bir kaç yazıda yaptığım gibi yine not alarak çalışacağım, hadi bakalım. 💃🏻
Map ve Set, bir kaç (bir çok) farkla objelere ve dizilere benzeyen iki yeni tip. Öncelikle Map tipinden başlayalım.

ES6: Map

Tanım

Map, bir yandan objelere, diğer yandan dizilere benzer. Objelerde olduğu gibi değerleri {nitelik:"değer"} olarak değil, dizilerdeki gibi [nitelik, değer] olarak tutar.
Öncelikle objelerden farkını anlayalım:
  • Obje niteliklerinde (property) sadece String ve Symbol tipleri kullanılabilirken, Map niteliklerinde fonksiyonlar, objeler veya herhangi bir ilkel tip kullanılabilir. Bu Map tipinin en önemli özelliklerinden biridir.
  • Bir obje sıralanabilir (iterable) değildir. Fakat Map sıralanabilirdir, dolayısıyla for-of döngülerinde kullanılabilir.
  • Map, objelerden farklı olarak nitelik ve değerleri ikili bir dizi olarak tutar. Dolayısıyla kullanımlarda bir Map tipini diziye çevirmek ve dizilerle çalışmak daha kolaydır.

Değer yazmak ve okumak

Bu tanımlardan sonra hadi bir Map tanımlayalım.
var map = new Map([
    ["a", "merhabadünya"],
    ["b", "helloworld"]
]);

map; //Map { a → "merhabadünya", b → "helloworld" }
Çıktının bir dizi çıktısı olmadığına dikkatinizi çekerim. Yepyeni bir şey bu 🐈
Yukarıda yaptığımızı şu şekilde de yapabiliriz.
var map = new Map();
map.set("a", "merhabadünya");
map.set("b", "helloworld");

map; //Map { a → "merhabadünya", b → "helloworld" }
Değerleri alırken .get metotunu kullanacağız.
var map = new Map();
map.set("a", "merhabadünya");
map.get("a") //merhabadünya
Tanımda nitelik olarak tüm ilkel tipleri kullanabileceğimizi söylemiştik. Hadi deneyelim.
const func = function(){ return "fiççiçi fiççu" }
var map = new Map();

map.set(func, "ismail abiiiiii");
map.set(null, "hooooppppp!");
map.set(undefined, "naptııın?"); //un mı defined?

map.get(func) //ismail abiiiiii
map.get(null) //hooooppppp
map.get(undefined); //naptııın?
Nitelik ve değere fonksiyon verip sonra onu çağırmak gibi bir şey deneyip PHP lobisine havamızı atabiliriz 😎
const f = function (){ return "what the function!" }
var map = new Map();
map.set(f, f);
map.get(f)(); //what the function

Değer silmek

Dizilerde bir elemanı silmek için farklı yöntemler olsa da, ES6 ile birlikte çoğunlukla gömülü filter fonksiyonunu kullanıyorduk. Map tiplerinde delete(key) ile bu işlemi yapacağız.
var map = new Map();
map.set("a", "merhabadünya");
map.set("b", "helloworld");
map.delete("a");
map; //Map { b → "helloworld" }
Tüm anahtar/değer ikililerini silmek için clear metotunu kullanacağız.
var map = new Map();
map.set("a", "merhabadünya");
map.set("b", "helloworld");
map.clear();
map; //Map {}

Döngülerle kullanmak

Anahtar ve değerleri ikili olarak almak için entries metotunu kullanabiliriz. Fakat bu metot bize objelerde olduğu gibi elemanları ikili olarak tanımlanmış bir dizi vermek yerine bir iterator objesi döndürüyor.
var map = new Map();
map.set("a", "aaaaa");
map.set("b", "bbbbb");

map.entries() // Map Iterator { }
Dolayısıyla entries metotundan dönen değeri iteratörü harekete geçirecek bir for-of döngüsünde kullanmamız gerekiyor.
var map = new Map();
map.set("a", "aaaaa");
map.set("b", "bbbbb");
for(var [key, value] of map.entries()){
    console.log(key, value)
}

//a aaaaa
//b bbbbb
Aslında burada map.entries() kullanarak Map tipindeki veriyi diziye çevirdik ve böylece dizi içindeki tanımlı olan iteratör fonksiyon çalıştı. Bunu aşağıdaki şekilde tanımlarsak da çalışacaktır.
var map = new Map();
map.set("a", "aaaaa");
map.set("b", "bbbbb");
for(var [key, value] of map){
    console.log(key, value)
}

//a aaaaa
//b bbbbb
Çünkü map tipinde de tanımlı bir iteratör fonksiyonu var!
var map = new Map();
map.set("a", "aaaaa");
map[Symbol.iterator] === map.entries // true
Öyleyse gömülü olan forEach metotunu da kullanabiliriz 😗
var map = new Map();
map.set("a", "aaaaa");
map.set("b", "bbbbb");
map.forEach(function(val){
    console.log(val)
})

//aaaaa
//bbbbb

Dönüşümler

Bir objenin Object.entries işlevinden dönen nitelik/değer ikili dizisini yeni bir Map tipinde tanımlayarak objeyi Map tipine çevirebiliriz.
var const = {
    a: 1,
    b: 2,
    c: 3
}

new Map(Object.entries(obj)) // Map(3) {"a" => 1, "b" => 2, "c" => 3}
Eğer Map tipindeki veri içinde filtreleme veya dönüşümler yapmak istiyorsak, bunu öncelikle diziye çevirerek gerekli işlevlerden geçirip daha sonra tekrar Map tipine çevirebiliriz.
var map = new Map([["a", 1], ["b", 2], ["c", 3]]);

new Map([...map].filter(([key, value]) => value < 3))
// Map(2) {"a" => 1, "b" => 2}
Burada Map tipini diziye çevirirken spread operatörünü kullandık. Yani Map aynı zamanda spreadable bir veri tipidir 🎉

ES6: Set

Set, değerleri tekil olan bir dizidir. Özellikleri itibariyle Map tipinden farklı olarak girilen değer için bir nitelik istenmez.
new Set([1, 2, 3, 4]);
// Set(4) {1, 2, 3, 4}
Tekil değerler aldığını söylemiştik.
var set = new Set([1,2,3,4,5,5,4,1])
// Set(4) {1, 2, 3, 4}

Değer okumak, yazmak ve silmek

new Set().add(1) şeklinde değer ekleyebilir, set.delete(1) ile değer silebilir ve herhangi bir değerin bulunup bulunmadığını set.has(1) ile alabiliriz.
var set = new Set();
set.has(1); //false

set.add(1);
set.has(1); //true

set.delete(1);
set.has(1) // false
// Set(3) {1, 2, 3}
Ekleme metodunu zincirleme kullanabiliriz.
new Set().add(1).add(2).add(3);
// Set(3) {1, 2, 3}
Bir Set içindeki değer sayısını almak için size niteliğini ve değerlerin tamamını silmek için clear metodunu kullanabiliriz.
var set = new Set().add(1).add(2).add(3);
set.size // 3
set.clear()
set.size // 0

Döngüler

Döngülerde kullanım Map tipinde olduğundan farksızdır. Sadece her bir elemandan gelen değer bir dizi olmadığı için bunu ayrıştırmamız gerekmeyecektir.
For-of döngülerinde diziye çevirerek veya doğrudan Set tipini kullanabiliriz.
var set = new Set([1, 2, 3]);

for(const el of set){
    console.log(el)
}

for(const el of [...set]){
    console.log(el)
}
Aynı şekilde forEach döngüsünde de kullanabiliriz.

Dönüşümler

Bir dizideki tekrarlanan değerleri silmek için bu diziyi öncelikle Set tipine, daha sonra tekrar diziye çevirebiliriz! Diziye çevirirken Set tipini spread edebiliriz.
const arr = [4, 1, "merhaba", "dünya", "merhaba", 2, 3, 4];
arr = [...new Set(arr)]
//[4, 1, "merhaba", "dünya", 2, 3]
Set tipini özel kılan şey, değerlerini bir küme olarak tutmasıdır. Elimizdeki dizilerin kesişimini, farkını veya birleşimini almak istiyorsak bu dizileri Set tipine çevirerek gerekli fonksiyonlardan geçirebiliriz.
Bir birleşim örneği görelim.
const arr1 = [1, 2, 3];
const arr2 = [4, 3, 2];
const set1 = new Set(arr1);
const set2 = new Set(arr2);
new Set([...set1, ...set2]);
// {1,2,3,4}
Kesişimleri, yani iki dizide bulunan ortak değerleri alalım.
const arr1 = [1, 2, 3,];
const arr2 = [4, 3, 2];
const set1 = new Set(arr1);
const set2 = new Set(arr2);
new Set([...set1].filter(x => b.has(x)));
// {2,3}
Bunlar gibi farklı küme işlemleri de yapılabilir.
Map ve Set tiplerinin genel kullanımını böylece görmüş olduk. Eğer ki burada spread, for-of veya diğer yapılara yabıncaysanız, blog ve kanalımdaki içeriklerde de bunlardan bahsetmeye çalışmıştım. Göz atabilirsiniz 👀
Sonraki yazı iteratörler üzerine olacak. Görüşmek üzere 💃🏻

© Samet 2017 - 2024