[Golang] 컬렉션 - 맵

이정훈·2023년 5월 26일
0

Golang

목록 보기
23/24
post-thumbnail

  • 배열, 슬라이스는 인덱스 번호를 임의대로 바꿀 수 없다는 것!

    • 예를 들어 단어 사전 배열 혹은 슬라이스를 이용해 만든다고 생각해 보자
      단어를 추가할 떄마다 인데스 0번부터 love, loyalty, root, submint... 등등의 단어를 순차적으로 저장하고 해당 인덱스 번호를 통해 저장돼 있는 값을 쓰거나 저장할 수 있는 것이 전부이다!
  • 그렇기 때문에 사전의 고유 형태인 단어 : 뜻형태로 저장할 수가 없어다ㅜ

  • 그래서 필요한 것이 바로 key값과 그에 해당하는 value 값을 매핑해 저장하는 Hash table이다!

  • Ruby에서의 hash와 python에서의 dicts와 같은 기능을 한다!

  • map은 key : value 형식으로 값을 매핑해서 저장!

  • 맵을 활용한다면 "love:사랑, root:뿌리, submin:제출하다"와 같은 형식으로 값을 저장!

  • 그리고 슬라이스와 맵의 공통점은 두 컬랙션 모두 값을 직접적으로 저장하는 것이 아닌 '참조 타입(Reference type)'이라는 점이다!

  • 따라서 선언과 값을 초기화 함에 있어서 슬라이스와 같은 방법과 이유를 가진다고 생각하면 된다!!

  • 맵의 선언은 var 맵이름 map[key자료형]value자료형형식으로 한다

    • 예를 들어 ing형 key값과 string형 value값을 가지는 a라는 이름의 맵을 선언할 때 var a map[int]string과 같이 선언!
      이렇게 선언만 하고 값을 초기화하지 않았다면 Nill map이 된다!!
  • 그래서 선언과 동시에 초기화 하는 것이 좋다... 막 왁 억 필수는 아닌듯

코드

package main

import "fmt"

func main() {
	var a map[int]string

	if a == nil {
		fmt.Println("nil map")
	}

	var m = map[string]string{ //key:value, 형식으로 초기화한다
		"apple":  "red",
		"grape":  "purple",
		"banana": "yellow",
	}

	fmt.Println(m, "\nm의 길이는", len(m))
}

출력

nil map
map[apple:red banana:yellow grape:purple] 
m의 길이는 3

map 변수의 추가, 갱신, 삭제

  • 메모리가 할당(make() 함수 혹은 {}를 사용한 값 초기화)됐으면 값을 추가, 갱신, 삭제할 수 있다.

  • 슬라이스는 값을 추가하기 위해 append()함수를 사용했지만, 맵에서 key값은 특별(unique)하기 때문에 맵이름[key] = value형식으로 값을 추가할 수 있다.

  • 주이! 이미 있는 key값에 다시 다른 value값을 저장한다면 최근 저장한 값으로 갱신!!

  • delete()함수를 이용해 저장된 값을 삭제!, delete(맵이름, key)형식을 입력하면 key값에 해당되는 value값이 삭제된다!

코드

package main

import "fmt"

func main() {
	//지역번호와 지역 저장
	var m = make(map[string]string)

	m["02"] = "서울특별시"
	m["031"] = "경기도"
	m["032"] = "충청남도"
	m["053"] = "대구광역시"

	fmt.Println(m)

	//동일한 key값으로 value값을 저장하면 갱신이 된다
	m["032"] = "인천"

	fmt.Println(m)

	//m에 있는 "031"key의 value와 함께 삭제
	delete(m, "031")

	fmt.Println(m)
}

출력

map[02:서울특별시 031:경기도 032:충청남도 053:대구광역시]
map[02:서울특별시 031:경기도 032:인천 053:대구광역시]
map[02:서울특별시 032:인천 053:대구광역시]

Map의 key 체크와 value 읽기

  • key가 사용되고 있는지(occupied), 만약 사용된다면 어떤 value값이 저장돼 있는지 알아야 할 때가 있다.

  • 이럴 때는 맵이름[key]의 값을 반환!

  • 컬랙션이름[인덱스]를 의미하는데 앞서 배운 두 컬렉션에서 컬렉션이름[인덱스]는 단순히 해당 컬렉션의 인덱스에 저장돼 있는 값을 반환!

    • 예를 들어, 배열이나 늣라이스의 arr[3]은 인데스 3에 저장돼 있는 값을 반환, 그리고 만약 인덱스의 범위를 넘는다면 에러가 발생!
  • 맵은 컬렉션[인덱스]의 사용에 있어서 다른 두 컬렉션과 차이점이 있다.

  • 맵이름[key]는 key에 저장돼 있는 value 값을 반환할 뿐만 아니라, 해당 키에 값이 존재하는지 안 하는지 즉, 사용하고 있는 key 값인지 아닌지 판별해주는 true/false 값도 반환합니다.

  • key 값이 사용되고 있다면 true를 반환, 그렇지 않다면 false를 반환

  • 그리고 존재하지 않는 key값을 입력했따면, 자료형에 따라 0이나 ""반환!

  • 정리하면 , m["031"] 은 "경기도"와 "true"를 반환, 하지만 이 용법에는 몇가지 주의사항이 있다!

    • 콘솔 출력 함수에 맵이름[key]을 바로 입력할 때는 key 값에 해당되는 value 값만 출력됩니다.
    • value 값과 true/false 값을 반환받기 위해서는 변수 두 개를 선언한 후에 각각 할당받아야 합니다.
      예를 들어 val, exist := 맵이름[key]형식으로 입력해야만 val에는 value 값이, exist에는 true/false 값이 초기화됩니다.
    • value 값만 반환받고 싶다면 변수 한 개만 선언해 할당받으면 됩니다.
      예를 들어 val := 맵이름[key]형식으로 입력하면 val에 value 값이 초기화됩니다. 꼭 두 개의 값을 반환하는 것은 아닙니다.
    • true/false 값만 반환받고 싶다면 _, bool변수형식으로 선언해 할당받으면 됩니다.
      예를 들어 _, exist := 맵이름[key]형식으로 입력하면 exist에 true/false 값이 초기화됩니다.
      왜냐하면 맵이름[key]는 꼭 'value, true/false' 순서로 반환하기 때문입니다.
      따라서 앞에 value 값을 받는 인자를 _, 용법을 써 생략한다면 true/false 값만 반환받을 수 있는 것입니다.

코드

package main

import "fmt"

func main() {
	//지역번호와 지역 저장
	var m = make(map[string]string)

	m["02"] = "서울특별시"
	m["031"] = "경기도"
	m["032"] = "인천"
	m["053"] = "대구광역시"

	fmt.Println(m["032"])
	fmt.Println(m["042"], "빈 칸입니다.") //string형태로 존재하지 않는 key값은 ""가 출력된다

	val, exist := m["02"] //존재하는 key
	fmt.Println(val, exist)

	val, exist = m["042"] //존재하지 않는 key
	fmt.Println(val, exist)

	val = m["053"] //value 값만 반환
	fmt.Println(val)

	_, exist = m["053"] //true/false 값만 반환
	fmt.Println(exist)

	//맵도 똑같이 len() 함수를 사용할 수 있다 하지만 cap() 함수는 사용할 수 없다
	fmt.Println(len(m))
}

출력

인천
 빈 칸입니다.
서울특별시 true
 false
대구광역시
true
4
  • 맵은 똑같이 len() 함수를 사용할 수 있다 하지만 cap() 함수는 사용할 수 없다

한 눈에 끝내는 고랭 기초 !!

profile
싱숭생숭늉

0개의 댓글