자바스크립트 E6(ES2015)가 나오면서, 편리한 자료구조인 ES2015-Collections( Map, Set )가 등장했습니다.


자바스크립트의 MapSet의 API가 타 언어에 비해 조금 다르더라도, 


타 언어와 많이 다르지 않기 때문에 사용하는것이 어렵진 않습니다.


다만, 순회하는 방법이 조금 독특하기 때문에 이번 포스팅을 하게 되었습니다.



forEach 메서드로 순회하기


Map, Set에서의 forEach( [Map or Set].prototype.forEach )는 ArrayforEach( Array.prototype.forEach )와 비슷하지만 조금 다릅니다.


Array의 forEach가 받는 콜백함수의 인수는 순서대로 , 인덱스, 배열 순으로 들어옵니다.


하지만 Map, Set에서의 forEach가 받는 콜백함수의 인수는 순서대로 , , 오브젝트(Map or Set) 로 들어옵니다.


Set의 콜백함수는 key 대신에 value2가 들어옵니다. value2는 value와 똑같습니다. 

아래의 예시와 "개별 값으로 순회 하기" 설명을 확인해주세요.


[ Ex) JavaScript / TypeScript ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// JavaScript
const map = new Map();
const set = new Set();
 
// TypeScript
const map = new Map<string, string>();
const set = new Set<string>();
 
map.set('name''Mommoo');
map.set('age' , 'secret');
 
set.add('Mommoo');
set.add('secret');
 
map.forEach((value, key, mapObject) => console.log(key +' , ' +value));
// name , Mommoo
// age , secret
 
set.forEach((value1, value2, setObject) => console.log(value1 +' , '+ value2));
// Mommoo , Mommoo
// secret , secret
cs



for.. of 문법으로 순회하기


forEach 방법은 순회 중간에 continue, break, return 과 같은 루프 기능을 못쓰지만, 


ES6(ES2015)에서 새로나온 for.. of 문법을 사용하면, 가능합니다.


Mapfor.. of로 호출되는 값은 벨류가 들어가 있는 배열 입니다.


Setfor.. of로 호출되는 값은 벨류입니다.


[ Ex) JavaScript ] 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const map = new Map();
const set = new Set();
 
map.set('name''Mommoo');
map.set('age' , 'secret');
 
set.add('Mommoo');
set.add('secret');
 
for ( let item of map ) {
  console.log(item[0+' , '+ item[1]);
}
// name , Mommoo
// age , secret
 
for ( let item of set ) {
  console.log(item);
}
// Mommoo
// secret
cs


TypeScript는 조금 까다롭습니다. 이유는 Iterable 속성 때문인데요. type iterable 속성때문에 for.. of가 컴파일이 되질 않습니다.


컴파일이 되지 않는 이유를 알고 싶으신 분은 다음 링크 2개를 참고해주세요.

http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html#new---downleveliteration

https://stackoverflow.com/questions/37699320/iterating-over-typescript-map


위의 JavaScript와 같이 사용하고 싶다면 컴파일러(tsconfig) 속성인 --downlevelIteration 을 켜주셔야 합니다.


아래의 예시는 속성을 키지 않고, 대안으로 ES6(ES2015) Array APIArray.from API를 사용하여 구현한 예제 입니다.


Array.from : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/from


[ Ex) TypeScript ] 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const map = new Map<string, string>();
const set = new Set<string>();
 
map.set('name''Mommoo');
map.set('age' , 'secret');
 
set.add('Mommoo');
set.add('secret');
 
for ( let item of Array.from(map) ) {
  console.log(item[0+' , '+ item[1]);
}
// name , Mommoo
// age , secret
 
for ( let item of Array.from(set) ) {
  console.log(item);
}
// Mommoo
// secret
cs



Iterator로 순회하기


ES2015-Collection인 MapSet는 순회가능한 Iterator입니다. ( IterableIterator )


2번째 방법인 For..of는 내부적으로 Iterator 속성을 이용하여 순회하게 됩니다.


이번에는 직접 Iterator 속성을 이용하여 순회하는 방법입니다. 


for.. of 와 마찬가지로 continue, break, return 과 같은 루프 기능을 사용 할 수 있습니다.


[ Ex) JavaScript / TypeScript ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// JavaScript
const map = new Map();
const set = new Set();
 
// TypeScript
const map = new Map<string, string>();
const set = new Set<string>();
 
map.set('name''Mommoo');
map.set('age' , 'secret');
 
set.add('Mommoo');
set.add('secret');
 
const mapIterator = map.entries();
 
while ( !mapIterator.next().done ) {
  const [key, value] = mapIterator.next().value;
  console.log(key +' , ' +value);  
}
// name , Mommoo
// age , secret
 
const setIterator = set.entires();
 
while ( !setIterator.next().done ) {
  const [value1, value2] = setIterator.next().value;
  console.log(value1 +' , ' +value2);  
// Mommoo , Mommoo
// secret , secret
cs



개별 값으로 순회 하기


지금까지 본것 처럼, ES2015-Collection은 IterableIterator로써, 두개의 값을 가집니다. 


Map은 각각 KeyValue로써, 가치가 매겨지는 반면, Set역시 두개의 값을 가지지만, 두개의 값은 서로 같습니다. 


Set이 필요없는 값을 가지고 있는 이유는 상위 개념인 ES2015-Collection의 다형성 관점으로 구현했기 때문입니다.


위의 예제와 같이 entries 메서드를 호출하면 두개의 값을 가진 IterableIterator인 반면,


두개의 값중 개별 값을 가진 IterableIterator를 만들 수 있습니다. 


첫번째 값은 keys 메서드로 호출하고, 두번째 값은 values 메서드를 호출하여 IterableIterator 객체를 만든 후,


2번째 방법 ( for.. of ) 또는 3번째 방법 ( iterator )으로 순회하시면 됩니다.



[ Ex) JavaScript / TypeScript ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// JavaScript
const map = new Map();
const set = new Set();
 
// TypeScript
const map = new Map<string, string>();
const set = new Set<string>();
 
map.set('name''Mommoo');
map.set('age' , 'secret');
 
set.add('Mommoo');
set.add('secret');
 
// 첫번째 값 ( 키 )
const mapSingleIterator = map.keys();
// 두번째 값 ( 벨류 )
const mapSingleIterator = map.values();
 
 
// 첫번째 값 ( 벨류 )
const setSingleIterator = set.keys();
// 두번째 값 ( 벨류 )
const setSingleIterator = set.values();
 
/** for of 방법 typescript는 Array.from 메서드로 변환 해야함. 2번째 방법 예시 참고 */
 
for ( let single of mapSingleIterator ) {
    console.log(single);
}
// name
// age
// ---- or -----
// Mommoo
// secret
 
for ( let single of setSingleIterator ) {
  console.log(single);
}
// Mommoo
// secret
 
 
/** iterator 방법 */
 
while ( !mapSingleIterator.next().done ) {
  const single = mapSingleIterator.next().value;
  console.log(single);  
}
// name or Mommoo
// age or secret
 
while ( !setSingleIterator.next().done ) {
  const single = setSingleIterator.next().value;
  console.log(single);  
}
// Mommoo
// secret
cs




준비한 내용은 여기까지 입니다.


읽어주셔서 감사합니다.



포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

List와 Map의 차이 2편이다.


1편에서는 List에 대해 포스팅 했고,


오늘은 Map에 대해 포스팅한다.


아래는 1편 URL이다.


http://mommoo.tistory.com/33



Map을 이용해 저장할때는 List처럼


뭉텅이로 저장하는것이 아니라, Map에 아이템을 저장할때마다, 빈 공간을 찾아 저장한다.


따라서 List보다는 데이터 저장속도가 느릴 수 있다.  Map의 가장 큰 특징이라면,


쌍을이루는 Key와 Value값을 이용한다는 것이다.


따라서 단순한 포지션(0~10 같은 인덱션)보다는, 저장하고 싶은 데이터가 특별한 Key값을


가질때 Map을 사용하는것이 좋다. 아래의 예시는 자바언어로 작성하였다.



HashMap<String,String> hashMap = new HashMap<>();

hashMap.put("Key1" , " 키값이 Key1인 Value 입니다. ");

hashMap.put("Key2" , " 키값이 Key2인 Value 입니다. ");

hashMap.put("Key3" , " 키값이 Key3인 Value 입니다. ");

hashMap.put("Key4" , " 키값이 Key4인 Value 입니다. ");


System.out.println(hashMap.get("key1");

System.out.println(hashMap.get("key2");

System.out.println(hashMap.get("key3");

System.out.println(hashMap.get("key4");



------------- consol  -----------------


키값이 Key1인 Value 입니다.

키값이 Key2인 Value 입니다.

키값이 Key3인 Value 입니다.

키값이 Key4인 Value 입니다.


위의 예시는 key값을 String으로 데이터도 String으로 작성하였다.


만약 동일한 Key값을 사용하면 기존의 Key값을 가지고 있는 value가 사라지고


후에 저장한 valuse 값이 셋팅이 된다. key만 다르다면 value 값이 중복되도 상관 없다.


Map은 콘솔에 찍힌거와 같이 키값이 의미가 있을때 좋은 자료구조 이다.


ArrayList안에 원하는 데이터를 검색하는 경우에는 0번부터 해당 데이터가 있을때까지


검색을 해야하지만, (원하는 데이터의 index를 모르는 경우) hashMap의 경우는 


key값을 통해서 빠르게 데이터를 검색한다. 


요소의 추가 삭제는 List보다 성능이 나을때가 많다. 따라서, 검색성능은 기본적으로 Map이 좋다.



정리하자면,  Map 은빈번한 검색과, 범위데이터가 아닌 특정 데이터를 순간마다 캐치해야할 때 유리한 자료구조이다. 





'용어정리 > 프로그래밍용어' 카테고리의 다른 글

URL 이란?  (2) 2016.06.14
URI 이란?  (0) 2016.06.13
List와 Map의 차이 (1)  (0) 2016.04.26
XML 이란?  (9) 2016.01.26
상수(constant) 와 리터럴(literal)이란?  (16) 2016.01.06

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

오늘 포스팅은 List와 Map에 대해 


비교분석 해보겠다.


상호간의 공통점은 데이터를 저장하는


자료구조 인 점이다.  하지만,


똑같이 데이터를 저장하지만, 데이터를 저장하는 구조는 다르다.


먼저 List는 Memory안의 특정한 동일 공간에 뭉텅이로 저장된다.


내부구현은 배열로 되어 있기 때문이다. 때문에 알맞는 데이터 저장공간만 


있다면 데이터 저장속도는 빠르다. 


또한, 순차적으로 데이터를 저장하므로, 데이터 특징이 


포지션별로 의미가 있을 때 사용하는 것이 좋다. 


아래는 자바로 작성한 예시이다. 


List와 Map의 프로그래밍적으로 개념은 같기때문에 어떤 언어든간에


똑같이 이해하면 된다.



ArrayList<String> arrayList = new ArrayList<>();


arrayList.add("0번 아이템 입니다.");

arrayList.add("1번 아이템 입니다.");

arrayList.add("2번 아이템 입니다.");

arrayList.add("3번 아이템 입니다.");

arrayList.add("4번 아이템 입니다.");

arrayList.add("5번 아이템 입니다.");


int index = 0;

for(String tempItem : arrayList){

  System.out.println((index++)+"번 : " + tempItem);

}


-------------------Consol---------------------------


0번 : 0번 아이템 입니다.

1번 : 1번 아이템 입니다.

2번 : 2번 아이템 입니다.

3번 : 3번 아이템 입니다.

4번 : 4번 아이템 입니다.

0번 : 5번 아이템 입니다.

 

foreach문을 썻지만 , 일반 for문으로 arrayList.get(position); 메서드를 써도 무방하다.


데이터가 6개 필요하므로 배열의 크기가 6을 충족하는 메모리 공간만 있으면


그곳에 배열자체를 저장한다. (JDK 1.7 아래 버전은 디폴트 배열 크기가 10이다.)


consol 출력처럼 포지션별로 의미가 있을때 유리하다.


예를 들어 쇼핑몰 페이지에서  쇼핑몰 아이템들을 화면에 나열 한다고 생각해보자. 


단순히 저장된 아이템 전부를 화면에 나열할 필요가 있으므로, 


순차적으로 저장된 데이터를 순차적으로 화면에 배치시키면 되는것이다.


이러한 경우는 ArrayList가 좋다. 하지만,


ArrayList안에 있는 데이터를 삽입/삭제가 빈번할때, 비효율적인 경우가 있다.


추가는 단순히 ArrayList 내부 배열의 크기를 바꾸고 기존 배열의 데이터를 추가하는데 그치지만,


원하는 포지션(인덱스)의 삽입/삭제는 이야기가 다르다. 


삽입/ 삭제는 해당 포지션 아래의 데이터들을 Copy 해야한다. (새로운 배열을 만든후,


기존 배열의 값을 포지션별로 다시 채워야한다.)


기존 배열의 크기를 늘린후 삽입/삭제 데이터를 처리하고 Copy된 데이터를 다시 붙인다.


따라서 ArrayList의 size가 큰 경우는 많은 양의 요소들을 Copy해야 하므로 내부적으로 성능이


떨어질 수 있는것이다.




정리하자면, ArrayList는 이이템의 빈번한 변경 없이,


데이터를 순차적으로 받고, 특정 데이터가 아닌 원하는 데이터 범위를 순차적으로 표현할때 유리한 자료구조라 볼 수 있다.


반면에, Map 은 다르다. 무엇이 다른지는 다음 포스팅때 이어가겠다.

 





'용어정리 > 프로그래밍용어' 카테고리의 다른 글

URI 이란?  (0) 2016.06.13
List와 Map의 차이 (2)  (0) 2016.04.27
XML 이란?  (9) 2016.01.26
상수(constant) 와 리터럴(literal)이란?  (16) 2016.01.06
Wrapper class(래퍼 클래스) 란?  (0) 2015.12.24

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

+ Recent posts