트랙
/
Go
Go
/
연습 문제
/
그로스 상점
그로스 상점

그로스 상점

학습 연습 문제

소개

Go에서 map은 키를 값에 대응시키는 내장 데이터 타입이에요. 다른 프로그래밍 언어에서 map을 딕셔너리, 해시 테이블, 키/값 저장소, 연관 배열 같은 개념으로 접해 본 적이 있을 거예요.

문법적으로 map은 이렇게 생겼어요:

map[KeyType]ElementType

각 키는 고유하다는 점도 중요해요. 같은 키에 값을 두 번 할당하면 그 키의 값이 덮어써져요.

맵을 만들려면 이렇게 하면 돼요:

  // With map literal
  foo := map[string]int{}

또는

  // or with make function
  foo := make(map[string]int)

다음은 맵으로 할 수 있는 몇 가지 연산이에요

  // Add a value in a map with the `=` operator:
  foo["bar"] = 42
  // Here we update the element of `bar`
  foo["bar"] = 73
  // To retrieve a map value, you can use
  baz := foo["bar"]
  // To delete an item from a map, you can use
  delete(foo, "bar")

맵에 없는 키의 값을 가져오려고 하면, 값 타입의 제로 값을 반환해요. 이 때문에 헷갈릴 수 있어요. 특히 ElementType의 기본값(예를 들어 int의 0)이 유효한 값일 때는 더 그래요. 맵에 키가 있는지 확인하려면 이렇게 하면 돼요

  value, exists := foo["baz"]
  // If the key "baz" does not exist,
  // value: 0; exists: false

지침

여러분의 친구가 Gross Store라는 오래된 도매점을 운영하고 있어요. 가게 이름은 친구가 파는 물건의 수량에서 나온 건데, 모두 그로스 단위로 되어 있거든요. 친구가 가게를 위한 판매 시점 관리(POS) 시스템을 만들어 달라고 부탁했어요. 우선 그 시스템의 프로토타입부터 만들어 보려고 해요. 프로토타입에서는 수량만 기록할 거예요. 친구가 도움이 되라고 측정 단위 목록을 알려줬어요:

단위 값
quarter_of_a_dozen 3
half_of_a_dozen 6
dozen 12
small_gross 120
gross 144
great_gross 1728

1. 프로그램에 측정 단위 저장하기

측정 단위를 사용하려면 프로그램에 그 단위를 저장해야 해요.

units := Units()
fmt.Println(units)
// Output: map[...] with entries like ("dozen": 12)

2. 새 고객 청구서 만들기

고객을 위한 새 (빈) 청구서를 만드는 함수를 구현해야 해요.

bill := NewBill()
fmt.Println(bill)
// Output: map[]

3. 고객 청구서에 품목 추가하기

이걸 구현하려면 다음을 해야 해요:

  • 주어진 unit이 units 맵에 없으면 false를 반환해요.
  • 그렇지 않으면 품목 이름을 키로 해서 고객 bill에 품목을 추가한 뒤 true를 반환해요.
  • 품목이 이미 청구서에 있다면, 주어진 unit에 해당하는 양만큼 수량을 늘려요.
bill := NewBill()
units := Units()
ok := AddItem(bill, units, "carrot", "dozen")
fmt.Println(ok)
// Output: true (since dozen is a valid unit)

반환 값의 타입은 bool이라는 점에 주의해요.

4. 고객 청구서에서 품목 제거하기

이걸 구현하려면 다음을 해야 해요:

  • 주어진 품목이 청구서에 없으면 false를 반환해요.
  • 주어진 unit이 units 맵에 없으면 false를 반환해요.
  • 새 수량이 0보다 작아지면 false를 반환해요.
  • 새 수량이 0이면 bill에서 품목을 완전히 제거한 뒤 true를 반환해요.
  • 그렇지 않으면 품목의 수량을 줄이고 true를 반환해요.
bill := NewBill()
units := Units()
ok := RemoveItem(bill, units, "carrot", "dozen")
fmt.Println(ok)
// Output: false (because there are no carrots in the bill)

반환 값의 타입은 bool이라는 점에 주의해요.

5. 고객 청구서에 있는 특정 품목의 수량 반환하기

이걸 구현하려면 다음을 해야 해요:

  • item이 청구서에 없으면 0과 false를 반환해요.
  • 그렇지 않으면 bill에 있는 품목의 수량과 true를 반환해요.
bill := map[string]int{"carrot": 12, "grapes": 3}
qty, ok := GetItem(bill, "carrot")
fmt.Println(qty)
// Output: 12
fmt.Println(ok)
// Output: true

반환 값의 타입은 int와 bool이라는 점에 주의해요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Go Exercism

그로스 상점 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Go 트랙을 개념 34개연습 문제 165개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.