[JS] Set๊ณผ Map

๋ชฉ์ฐจ

etc-image-0
Ch.37 Set๊ณผ Map

 

๐Ÿ“ŒSet

= ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์œ ์ผํ•œ ๊ฐ’๋“ค์˜ ์ง‘ํ•ฉ

  • ์ค‘๋ณต์ด ์•ˆ๋จ
  • ์ˆœ์„œ์— ์˜๋ฏธ๊ฐ€ ์—†์Œ
  • ์ธ๋ฑ์Šค๋กœ ์š”์†Œ ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅ

 

Set ๊ฐ์ฒด ์ƒ์„ฑ = Set ์ƒ์„ฑ์ž ์‚ฌ์šฉ

// ๋นˆ๊ฐ์ฒด 
const set = new Set()
console.log(set)   // Set(0) {size: 0}

// ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ธ์ˆ˜๋กœ ๋ฐ›์Œ
const set1 = new Set([1, 2, 3, 4])
console.log(set1)  // Set(3) {1, 2, 3}
const set2 = new Set('hello')
console.log(set2)  // Set(4) {'h', 'e', 'l', 'o'} ์ค‘๋ณต๋œ l์€ ํ•œ๊ฐœ๋งŒ ๋“ค์–ด๊ฐ

 

์ค‘๋ณต๋œ ์š”์†Œ๊ฐ€ ์ธ์ˆ˜๋กœ ๋“ค์–ด๊ฐ€๋ฉด ํ•œ๊ฐœ๋งŒ ๋“ค์–ด๊ฐ -> ์ด๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐฐ์—ด์—์„œ ์ค‘๋ณต๋œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

const uniq = array => [... new Set(array)]
console.log(uniq([1, 2, 2, 2, 3, 3, 4, 5]))   // [1, 2, 3, 4, 5]

 

 

Set.prototype.size = ๊ฐ์ฒด์˜ ์š”์†Œ ๊ฐœ์ˆ˜ ํ™•์ธ

const {size} = new Set([1, 2, 3, 3])  // set๋งŒ๋“ค๊ณ  set.size๋กœ ํ•ด๋„ ๊ฐ™์€ ๊ฐ’
console.log(size)  // 3

 

Set.prototype.add = ์š”์†Œ ์ถ”๊ฐ€

const set = new Set()
set.add(1)
console.log(set)   // Set(1) {1}

// ์—ฐ์†์œผ๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅ -> add๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์—
set.add(2).add(3)
console.log(set)  // Set(3) {1, 2, 3}

// ์ค‘๋ณต๋œ ์š”์†Œ๋Š” ๋ฌด์‹œ๋จ
set.add(1)
console.log(set)  // Set(3) {1, 2, 3}


// NaN์˜ ๊ฒฝ์šฐ..
console.log(NaN === NaN)  // false์ง€๋งŒ, set์—์„œ๋Š” ๊ฐ™๋‹ค๊ณ  ํ‰๊ฐ€๋จ
set.add(NaN).add(NaN)  // ํ•œ๊ฐœ๋งŒ ๋“ค์–ด๊ฐ

 

Set.prototype.has = ์š”์†Œ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ

const set = new Set([1, 2, 3])
console.log(set.has(1))  // true
console.log(set.has(5))  // false

 

Set.prototype.delete = ์š”์†Œ ์‚ญ์ œ

์‚ญ์ œ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•จ

const set = new Set([1, 2, 3])
console.log(set.delete(1))  // true
console.log(set)   // Set(2) {2, 3}

set.delete(5)  // ๋ฌด์‹œ๋จ
set.delete(3).delete(2) // ์—ฐ์†์œผ๋กœ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ

 

 

Set.prototype.clear = ๋ชจ๋“  ์š”์†Œ ์‚ญ์ œ

undefined ๋ฐ˜ํ™˜

const set = new Set([1, 2, 3])
console.log(set.clear())   // undefined
console.log(set)    // Set(0) {size: 0}

 

Set.prototype.forEach = ์š”์†Œ ์ˆœํšŒ

์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ์ธ์ˆ˜

  • ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜: ํ˜„์žฌ ์ˆœํšŒ ์ค‘์ธ ์š”์†Œ๊ฐ’
  • ๋‘๋ฒˆ์งธ ์ธ์ˆ˜: ํ˜„์žฌ ์ˆœํšŒ ์ค‘์ธ ์š”์†Œ๊ฐ’
  • ์„ธ๋ฒˆ์งธ ์ธ์ˆ˜: ํ˜„์žฌ ์ˆœํšŒ ์ค‘์ธ Set ๊ฐ์ฒด ์ž์ฒด
const set = new Set([1, 2, 3])
set.forEach((v, v2, set) => console.log(v, v2, set))
// 1 1 Set(3) {1, 2, 3}
// 2 2 Set(3) {1, 2, 3}
// 3 3 Set(3) {1, 2, 3}

 

๋”๋ณด๊ธฐ

์ฒซ๋ฒˆ์งธ๋ž‘ ๋‘๋ฒˆ์งธ๊ฐ€ ๋˜‘๊ฐ™์€๋ฐ ์™œ ๊ตณ์ด ์ด๋ ‡๊ฒŒ ๋ฐ›์„๊นŒ

-> Array.prototype.forEach๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ธฐ ์œ„ํ•ด์„œ. 

array์˜ ๊ฒฝ์šฐ๋„ ๋˜‘๊ฐ™์ด ์„ธ๊ฐœ๋ฅผ ๋ฐ›๋Š”๋ฐ, ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ์ˆœํšŒ์ค‘์ธ ์š”์†Œ์˜ ์ธ๋ฑ์Šค์ž„. ๊ทผ๋ฐ set๋Š” ์ธ๋ฑ์Šค๊ฐ€ ์—†์œผ๋‹ˆ๊นŒ ๊ทธ๋ƒฅ ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋ž‘ ๊ฐ™์€ ๊ฑธ๋กœ...

 

Set ๊ฐ์ฒด๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋‹ค.

๊ทธ๋ž˜์„œ for ... of๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ณ , ์Šคํ”„๋ ˆ๋“œ ๋ฌธ๋ฒ•๊ณผ ๋ฐฐ์—ด ๋””์ŠคํŠธ๋Ÿญ์ฒ˜๋ง๋„ ๊ฐ€๋Šฅ

const set = new Set([1, 2, 3])

for (const v of set) {
	console.log(v) // 1 2 3
}

console.log([...set]) // [1, 2, 3]

 

Set๋ฅผ ํ™œ์šฉํ•ด์„œ ์ง‘ํ•ฉ ์—ฐ์‚ฐ์„ ๋งŒ๋“ค์–ด๋ณด์ž

(1) ๊ต์ง‘ํ•ฉ

Set.prototype.intersection = function(set) {
    return new Set([...this].filter(v => set.has(v)))
}

 

(2) ํ•ฉ์ง‘ํ•ฉ

Set.prototype.union = function (set) { 
	return new Set([...this, ...set])
}

 

(3) ์ฐจ์ง‘ํ•ฉ

Set.prototype.difference = function (set) {
	return new Set([...this].filter(v => !set.has(v))
}

 

 


๐Ÿ“ŒMap

= ํ‚ค์™€ ๊ฐ’์˜ ์Œ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์ปฌ๋ ‰์…˜

etc-image-1
Map๊ฐ์ฒด์™€ ๊ฐ์ฒด(object)์™€์˜ ์ฐจ์ด์ 

 

Map ๊ฐ์ฒด ์ƒ์„ฑ = Map์ƒ์„ฑ์ž ์‚ฌ์šฉ

์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์œผ๋ฉฐ, ํ‚ค์™€ ๊ฐ’์˜ ์Œ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•จ

// ๋น„์—ˆ์„ ๋•Œ
const map = new Map()
console.log(map)   // Map(0) {size: 0}

// ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ์ธ์ˆ˜๋กœ
const map1 = new Map([['key1', 'value1'], ['key2', 'value2']])
console.log(map1)   // Map(2) {'key1' => 'value1', 'key2' => 'value2'}

const map2 = new Map([1, 2])  // TypeError: Iterator value 1 is not an entry object
// ๋ฌด์กฐ๊ฑด [['key1', 'value1'], ['key2', 'value2']] ์ด๋Ÿฐ ํ˜•์‹์œผ๋กœ ๋“ค์–ด์™€์•ผํ•˜๋Š”๋ฐ,
// ์—ฌ๊ธฐ์„  [1, 2]๋กœ ๋“ค์–ด์˜ด. ๊ทธ๋ž˜์„œ 1์„ ['key1', 'value1']์˜ ํ˜•์‹์œผ๋กœ ํ•ด์„ํ•˜๋ ค๋‹ค๊ฐ€ ์‹คํŒจ

// key๊ฐ€ ์ค‘๋ณต๋˜๋ฉด ๋’ค์— ๋“ค์–ด์˜ค๋Š” value๋กœ ๋ฎ์–ด์”Œ์›Œ์ง
const map3 = new Map([['key1', 'value1'], ['key1', 'value2']])
console.log(map3)  // Map(1) {'key1' => 'value2'}

 

 

Map.prototype.size = ๊ฐฏ์ˆ˜ ํ™•์ธ

Map.prototype.set = ์š”์†Œ ์ถ”๊ฐ€

const map = new Map()
map.set('key1', 'value1').set('key2', 'value2')  // ์—ฐ์† ํ˜ธ์ถœ ๊ฐ€๋Šฅ
console.log(map)   // Map(2) {'key1' => 'value1', 'key2' => 'value2'}

// ๊ฐ์ฒด๋ฅผ key๋กœ ์“ฐ๋Š”๊ฒƒ๋„ ๊ฐ€๋Šฅ
const user1 = { name: '์ฒ ์ˆ˜' }
const user2 = { name: '์˜ํฌ' }

const userScores = new Map()
userScores.set(user1, 90)
userScores.set(user2, 85)

console.log(userScores)   // Map(2) {{name: '์ฒ ์ˆ˜'} => 90, {name: '์˜ํฌ'} => 85}

 

Map.prototype.get = ์š”์†Œ ๊ฐ€์ ธ์˜ค๊ธฐ

const map = new Map()
map.set('key1', 'value1').set('key2', 'value2')
console.log(map.get('key1'))  // value1
console.log(map.get('key6'))  // ์—†์œผ๋ฉด undefined

 

Map.prototype.has = ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ

Map.prototype.delete = ์š”์†Œ ์‚ญ์ œ

const map = new Map()
map.set('key1', 'value1').set('key2', 'value2')
console.log(map.delete('key1'))  // true
console.log(map)  // Map(1) {'key2' => 'value2'}

console.log(map.get('key6'))  // ์—†์œผ๋ฉด undefined(๋ฌด์‹œ๋จ)
console.log(map)  // Map(1) {'key2' => 'value2'}

 

Map.prototype.clear = ์ผ๊ด„ ์‚ญ์ œ

 

Map.prototype.forEach = ์š”์†Œ ์ˆœํšŒ

์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ์ธ์ˆ˜

  • ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜: ํ˜„์žฌ ์ˆœํšŒ ์ค‘์ธ ์š”์†Œ๊ฐ’
  • ๋‘๋ฒˆ์งธ ์ธ์ˆ˜: ํ˜„์žฌ ์ˆœํšŒ ์ค‘์ธ ์š”์†Œํ‚ค
  • ์„ธ๋ฒˆ์งธ ์ธ์ˆ˜: ํ˜„์žฌ ์ˆœํšŒ ์ค‘์ธ Map ๊ฐ์ฒด ์ž์ฒด
const fruits = new Map([
    ['์‚ฌ๊ณผ', 500],
    ['๋ฐ”๋‚˜๋‚˜', 700],
    ['์˜ค๋ Œ์ง€', 600]
])

fruits.forEach((value, key, map) => {
    console.log(`value: ${value}`)
    console.log(`key: ${key}`)
    console.log(`์ „์ฒด Map:`, map)
    console.log('---------------')
})

// ์ถœ๋ ฅ ๊ฒฐ๊ณผ:
// value: 500
// key: ์‚ฌ๊ณผ
// ์ „์ฒด Map: Map(3) { '์‚ฌ๊ณผ' => 500, '๋ฐ”๋‚˜๋‚˜' => 700, '์˜ค๋ Œ์ง€' => 600 }
// ---------------
// value: 700
// key: ๋ฐ”๋‚˜๋‚˜
// ์ „์ฒด Map: Map(3) { '์‚ฌ๊ณผ' => 500, '๋ฐ”๋‚˜๋‚˜' => 700, '์˜ค๋ Œ์ง€' => 600 }
// ---------------
// value: 600
// key: ์˜ค๋ Œ์ง€
// ์ „์ฒด Map: Map(3) { '์‚ฌ๊ณผ' => 500, '๋ฐ”๋‚˜๋‚˜' => 700, '์˜ค๋ Œ์ง€' => 600 }
// ---------------


// ์Šคํ”„๋ ˆ๋“œ ๋ฌธ๋ฒ•
console.log([...fruits])  // [['์‚ฌ๊ณผ', 500], ['๋ฐ”๋‚˜๋‚˜', 700], ['์˜ค๋ Œ์ง€', 600]]

 

keys, values, entries ๋ฉ”์„œ๋“œ

-> ๊ฐ์ž Map ๊ฐ์ฒด์˜ ์š”์†Œํ‚ค, ์š”์†Œ๊ฐ’, ์š”์†Œํ‚ค + ์š”์†Œ๊ฐ’์„ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฉด์„œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์ธ ๊ฐ์ฒด๋กœ ๋ฐ˜ํ™˜

const fruits = new Map([
   ['์‚ฌ๊ณผ', 500],
   ['๋ฐ”๋‚˜๋‚˜', 700],
   ['์˜ค๋ Œ์ง€', 600]
])

console.log(fruits.keys())  // [Map Iterator] { '์‚ฌ๊ณผ', '๋ฐ”๋‚˜๋‚˜', '์˜ค๋ Œ์ง€' }
console.log(fruits.values())  // [Map Iterator] { 500, 700, 600 }
console.log(fruits.entries())  // [Map Entries] { [ '์‚ฌ๊ณผ', 500 ], [ '๋ฐ”๋‚˜๋‚˜', 700 ], [ '์˜ค๋ Œ์ง€', 600 ] }