#2 Array, Set, Map

공부의 기록·2022년 1월 30일
1

JavaScript

목록 보기
8/16
post-thumbnail

Introduce

본 문서는 2022년 1월 30일 에 작성되었습니다.

본 문서는 JavaScript 의 배열을 이해하고 내장 함수들을 자유롭게 사용하는 것을 목적으로 하고있습니다.


Theory

다음의 클래스들에 대한 내용을 담고 있습니다.

  1. Array
  2. Set
  3. Map

각각 Constructor, Function, Example 로 구성했습니다.

✅ Constructor

Array, Set, Map 의 생성자에 대한 내용입니다.


Array - mdn

Array 는 List 자료구조 로 구현되었습니다.
JavaScript 의 배열은 다음과 같은 특징을 지니고 있습니다.

  1. 길이가 가변적이다.
  2. 모든 요소에 다른 자료형이 담길 수 있다.
  3. 모든 인스턴스에서 Array 클래스의 함수를 사용할 수 있다.

또한 약식으로 인스턴스를 생성할 수도 있습니다.

const array1=new Array(); // ok
const array2=new Array(3); // ok
const array3=new Array(10,20,30); // ok
const array4=new Array([10,20,30]); // check!!!
const array5=new Array(...[10,20,30]); // ok
const array6=[]; // ok
const array7=[10,20,30]; // ok
const array8=new Array({name:"hello"}); // ok
const array9=new Array({name:"hello"},30); // ok
const array10=new Array([{name:"hello"},30]); // check!!!
const array11=new Array(...[{name:"hello"},30]); // ok

# Check => [map4, map10]

위에서 주의할 점은,
Array 클래스 생성자에 매개변수로 배열을 넘겨줄 수 있다는 점이다.

array4 를 보면 길이가 3인 배열이 나올 것 같지만, 실제로 콘솔 창을 통해서 출력해보면 길이가 1인 배열이 나온다.
역시나 array10 을 봐도 길이가 1인 배열이 나온다.


Set - mdn

Set 은 이름부터 알 수 있듯, Set 자료구조 로 구현되었습니다.
따라서 다음과 같은 특징을 지니고 있습니다.

  1. 길이가 가변적이다.
  2. 모든 요소에 다른 자료형이 담길 수 있다.
  3. 모든 인스턴스에서 Set 클래스의 함수를 사용할 수 있다.
  4. 모든 요소는 서로 중복 블가능하다.
const set1=new Set(); // ok
const set2=new Set(10); // not-ok
const set3=new Set([10]); // ok
const set4=new Set(...[10]); // not-ok
const set5=new Set({name:"hello"}); // not-ok
const set6=new Set({name:"hello"},30); // not-ok
const set7=new Set([{name:"hello"},30]); // ok
const set8=new Set(...[{name:"hello"},30]); // not-ok

# not-ok => [map2, map4, map5]

위에서 주의할 점은,
Set 클래스 생성자에 non iterable 은 넘겨줄 수 없다 는 점이다.

이 경우 변수명 is not iterable (cannot read property symbol(Symbol.iterator)) 에러가 뜬다.

set2, set4 는 동일한 10이다.
set5 는 일반 객체이다.

# not-ok => [map6, map8]

동시에 주의할 점은,
여러 개의 매개변수를 넘겨주는 것이 배열을 넘겨준 것이 아니라는 점이다.

이 경우에도 변수명 is not iterable (cannot read property symbol(Symbol.iterator)) 에러가 뜬다.

set6, set8 은 일반 객체와 10 이라는 매개변수 두 개를 넘겨준 것이다.


Map -mdn

Map 은 이름부터 알 수 있듯, Map 자료구조 로 구현되었습니다.
따라서 다음과 같은 특징을 지니고 있습니다.

  1. 길이가 가변적이다.
  2. 모든 요소에 다른 자료형이 담길 수 있다.
  3. 모든 인스턴스에서 Map 클래스의 함수를 사용할 수 있다.
  4. 모든 Key 는 중복 불가능하지만, Value 는 중복가능하다.

Map 의 생성자는 오직 다음의 2가지 방법만 존재합니다.

  1. new Map()
  2. new Map(iterable)
const map1=new Map(); // ok
const map2=new Map([1,10]); // not-ok
const map3=new Map([[1,10]]); // ok
const map4=new Map([[1,10],[3,30]]); // ok
const map5=new Map([[1,10],[1,30]]); // Check!!
const map6=new Map([[1,10],["1",30]]); // Check!!

# not-ok => [map2]

Map 에 넘겨줄 수 있는 매개변수는 Entry Object 로 이루어진 Iterable 인스턴스입니다.

Entry 는 Key-Value 로 이루어진 한쌍을 의미합니다.

# Check => [map5]

전술한 바와 같이 Key 는 중복 불가능한 특징을 가지고 있습니다.
따라서 map5 를 실행시켜보면 다음과 같은 결과를 얻을 수 있습니다.

Map(1) {1=>30}

# Check map6

전술한 바와 같이 Key 는 중복 불가능한 특징을 가지고 있습니다.
하지만 map6는 1, '1' 으로 서로 다른 값임을 알 수 있습니다.

Map(2) {1=>10, '1'=>30}


✅ Array.Function

Array 클래스 에는 다음과 같은 내장 함수가 있다.

  1. Insert, Pull 관련 함수
  2. Index 관련 함수
  3. Find 관련 함수
  4. Reverse 함수
  5. Sort 함수
  6. Tour 함수
  7. Test 함수
  8. Copy 함수
  9. Entry 함수

내장 함수의 수가 너무 많다고 느낀다면,
push, pop, forEach, map 등의 함수만 사용해도 대부분의 문제를 해결할 수 있다.


1. Insert, Pull 함수

삽입 및 추출 관련 함수이다.

  1. Array.prototype.push()
  2. Array.prototype.pop()
  3. Array.prototype.unshift()
  4. Array.prototype.shift()

1,2번은 배열의 끝에서부터 실행된다.
3,4번은 배열의 시작부터 실행된다.

1,3번은 삽입 기능을 2,4번이 제거 기능을 담당한다.


2. Index 함수

값에 의한 인덱스 반환 함수이다.

  1. Array.prototype.indexOf()
  2. Array.prototype.lastIndexOf()

매개변수로 넘겨준 값이 있는지 확인하고

존재한다면 인덱스를 반환 하며
존재하지 않는다면 -1를 반환 한다.

indexOf 는 첫 요소를 반환 한다.
lastindexOf 는 마지막 요소를 반환 한다.


3. Find 함수

조건에 의한 탐색 함수이다.

  1. Array.prototype.find()
  2. Array.prototype.findIndex()

매개변수로 넘겨준 함수를 만족하는 값이 있는지 확인하고

존재한다면 find() 는 첫 값을 반환 하고
존재하지 않는다면 find() 는 undefined 를 반환 한다.

존재한다면 findIndex() 는 첫 인덱스를 반환 하고
존재하지 않는다면 findIndex() 는 -1 를 반환 한다.


4. Reverse 함수

배열을 뒤집는데 사용한다.

  1. Array.prototype.reverse()

해당 메서드를 실행하면 원 배열이 뒤집한다.


5. Sort 함수

배열을 정렬하는데 사용된다.

  1. Array.prototype.sort();

매개변수를 주지 않으면 문자열을 기준으로 정렬 한다.
매개변수로 함수를 넘겨서 새로운 기준으로 정렬 할 수 있다.

아래와 같이 작성하여 오름차순 정렬을 실행할 수 있다.

const array=[70,50,40,10,90,100].sort((a,b)=>a-b);

6. Test 함수

Boolean 을 리턴하는 함수들이다.

  1. Array.prototype.includes(값);
  2. Array.prototype.every(함수);
  3. Array.prototype.some(함수);

2번은 모든 요소가 true 여야 true 를 반환한다.
3번은 하나라도 true 면 true 를 반환한다.

또한 some() 은 프로토타입 배열의 길이가 0 이면 무조건 false 를 리턴한다.


7. Copy 함수

복사와 관련된 기능을 하는 함수이다.

  1. Array.of(값)
  2. Array.from(값 혹은 값,함수)
  3. Array.prototype.values();

1번은 해당 값이 들어있는 배열를 만들어낸다.
단, Deep Copy 이기 때문에 배열이 담긴 주소 를 반환하면 한 주소값을 두 배열이 가르키는 현상이 발생한다.

Array.of(10); // [10] 길이 1
Array.of(10,20,30); // [10,20,30] 길이 3
Array.of([10,20,30]); //[[10,20,30]] 길이 1

2번은 해당 값이 iterable 하다면 이를 통해서 배열을 만들어낸다.
단, Shallow Copy 이기 때문에 Array.of() 에서 발생하는 문제가 없다.

Array.from("hello"); // ["h","e","l","l","o"] 길이 5
Array.from([10,20,30], x=>x+10); // [20, 30, 40] 길이 3

3번은 프로토타입 배열의 값을 카피해 새로운 Iterator 를 반환합니다.
Tour 함수의 map() 개념은 비슷하나 리턴 타입이 다릅니다.

const newArray=[10,20,30].values();

8. Tour 함수

배열의 모든 칸을 순회하며 내부 함수를 실행합니다.

  1. Array.prototype.forEach()
  2. Array.prototype.map()
  3. Array.prototype.reduce()
  4. Array.prototype.reduceRight()
  5. Array.prototype.fill()
  6. Array.prototype.filter()
  7. Array.prototype.flat()
  8. Array.prototype.flatMap()

Tour, 순회 함수의 경우 꼭 정답이 될 수 없습니다.

for문 for-of 문으로도 배열의 각 칸을 충분히 순회할 수 있습니다. 따라서 이에 대한 설명은 따로 하지 않겠습니다.

다만,
flat()과 flatMap() 은 매우 흥미로우니 시간이 난다면 MDN 을 확인해봅시다.

9. Entry 함수

Map 에 담기는 Entries 형태로 데이터를 추출하는 함수이다.

  1. Array.prototype.entries()

✅ Set.Function

  1. Insert, Pull 관련 함수
  2. Test 관련 함수
  3. Copy 관련 함수
  4. Clear 관련 함수
  5. Tour 관련 함수
  6. Entry 관련 함수

1. Insert, Pull 함수

매개변수로 넘긴 값을 넣거나 삭제합니다.

  1. Set.prototype.add()
  2. Set.prototype.delete()

2. Test 함수

매개변수로 넘긴 값의 존재 유무를 확인합니다.

  1. Set.prototype.has()

3. Copy 함수

Iterator 를 반환합니다.

  1. Set.prototype.values()

4. Clear 함수

Set 인스턴스의 값을 모두 비우고 초기화합니다.

  1. Set.prototype.clear()

5. Tour 함수

Set 의 모든 칸을 순회하며 내부 함수를 실행합니다.

  1. Set.prototype.forEach((value,key,set)=>{/ 프로세스 /});
const set1=new Set([10,20,30]);
set1.forEach((value,key,set)=>{
  console.log(value,key,set);
  // 10 10 > Set(3) {10,20,30}
  // 20 20 > Set(3) {10,20,30}
  // 30 30 > Set(3) {10,20,30}
});

const set2=new Set([[10,20,30]]);
set2.forEach((value,key,set)=>{
  console.log(value,key,set);
  // > (3)[10 20 30] > (3)[10 20 30] > Set(3) {10,20,30}
});

6. Entry 함수

Map 에 담기는 Entries 형태로 데이터를 추출하는 함수이다.

  1. Set.prototype.entries()

✅ Map.Function

  1. Insert, Pull 관련 함수
  2. Test 관련 함수
  3. Copy 관련 함수
  4. Clear 관련 함수
  5. Tour 함수
  6. Entry 함수

1. Insert, Pull 함수

매개변수로 넘긴 값을 넣거나 찾거나 삭제합니다.

  1. Map.prototype.set(키,값)
  2. Map.prototype.get(키)
  3. Map.prototype.delete(키)

2. Test 함수

매개변수로 넘긴 값의 존재 유무를 확인합니다

  1. Map.prototype.has()

3. Copy 함수

Iterator 를 반환합니다.

4. Clear 함수

Map 인스턴스의 키-값 엔트리를 모두 비우고 초기화합니다.

  1. Map.prototype.clear()

5. Tour 함수

Map의 모든 칸을 순회하며 내부 함수를 실행합니다.

  1. Map.prototype.forEach((value,key,map)=>{ / 프로 세스 / });
const newMap=new Map([[11,"hello1"],[22,"hello2"],[33,"hello3"]]);
newMap.forEach((value,key,map)=>console.log(value,key,map));

// hello1 11 > Map(3) {11=>"hello1", 22=>"hello2", 33=>"hello3"}
// hello2 22 > Map(3) {11=>"hello1", 22=>"hello2", 33=>"hello3"}
// hello3 33 > Map(3) {11=>"hello1", 22=>"hello2", 33=>"hello3"}

6. Entry 함수

Map 에 담기는 Entries 형태로 데이터를 추출하는 함수이다.

  1. Map.prototype.entries()

✅ Example

forEach(), map()

열거 가능한 속성을 가진 배열 등의 프로토타입은 두 함수를 내장하고 있습니다.

즉, Array 또한 이를 가지고 있습니다.
forEach 는 배열의 각 칸을 순회하며 내부를 실행하고 리턴값은 없습니다.
map 은 배열의 각 칸을 순회하며 내부를 실행하고 배열을 리턴합니다.
비슷한 함수로는 find(), filter() 등이 있습니다.
내부 로직이 동일하므로 find(), filter() 는 설명하지 않습니다.

// 인자 2개를 받고 이를 사용하는 경우
Array.prototype.forEach((value,key)=>{
  console.log(value);
  console.log(key);
});
// 인자를 1개 사용할 경우 (value) 를 value 로 작성 가능
// 코드를 1줄만 작성할 경우 {console.log(value)} 를 console.log 로 작성 가능
Array.prototype.forEach(value=>console.log(value));

단, map() 함수의 경우는 다음을 주의해야 한다.

Array.prototype.map(value=>return value); // Error! 필드가 없으면 return 을 생략해야한다.
Array.prototpye.map(value=>value); // Ok!

sort()

sort() 함수는 내부에 매개변수를 넘겨주지 않으면 문자열 값을 기준으로 정렬 합니다.

따라서 사용 목적에 따라 적절하게 정렬 알고리즘을 구현 하여 넘겨줘야 합니다.

Array.prototype.sort((a,b)=>a-b); // 오름차순 정렬
Array.prototype.sort((a,b)=>b-a); // 내림차순 정렬

join()

join() 함수는 배열을 하나의 문자열 로 합칩니다.

매개변수를 넘겨주지 않으면 ','을 각 문자열 사이에 넣어줍니다.
빈 문자열을 넘겨주면 ""을 각 문자열 사이에 넣어줍니다.

숫자 문자열과 영단어 in 2021 카카오 채용연계형 인턴쉽
배열 형태로 주어진 입력값은 소문자 영어와 숫자로 이루어져있다.
영어는 전부 숫자로 바꿔야 한다.

추천 수가 많았던 신기한 코드

function solution(s) {
    let numbers = ["zero", "one", "two", "three", "four",
    		"five", "six", "seven", "eight", "nine"];
    var answer = s;
    for(let i=0; i< numbers.length; i++) {
        let arr = answer.split(numbers[i]);
        answer = arr.join(i);
    }
    return Number(answer);
}

입력값이 아닌 기준값으로 반복을 한 것이 엄청 신기했다.
단, 이 경우 입력값이 1개여도 무조건 10번을 반복하는 문제가 보였다.

내가 제출한 코드

const testMap=new Map();
testMap.set("zero",0);
testMap.set("one",1);
testMap.set("two",2);
testMap.set("three",3);
testMap.set("four",4);
testMap.set("five",5);
testMap.set("six",6);
testMap.set("seven",7);
testMap.set("eight",8);
testMap.set("nine",9);
function solution(text) {
    let result="";
    let tmpText="";
    for (const word of text) {
        if (isNaN(word)) {
            tmpText+=word;
        } else {
            result+=word;
        }
        if (testMap.has(tmpText)) {
            result+=testMap.get(tmpText);
            tmpText="";
        }
    }
    return +result;
}

가독성이 너무 떨어지는 것 같지만,
입력값의 각 칸을 순회하면서 숫자가 아닌 경우만 testMap 에서 탐색하는 절차를 넣었다.

reduce()

redcue() 함수는 배열의 각 칸을 누적 순회합니다.

Array.prototype.reduce((누적값, 현재값)=>누적값+현재값);

없는 숫자 더하기 in 월간 코드 챌린지 3
0부터 9까지의 숫자의 일부가 들어있는 numbers 배열 을 받으면,
0부터 9까지의 숫자 중 찾을 수 없는 수를 모두 더한 후 return 하는 solution 함수 구현

추천 수가 많았던 신기한 코드

function solution(numbers) {
    return 45 - numbers.reduce((cur, acc) => cur + acc, 0);
}

0부터 9까지의 총합 45 에서 존재하는 숫자를 빼는 식으로 계산한 것이 인상깊었다.

내가 제출한 코드

function solution(numbers) {
    const numberSet=new Set([...numbers]);
    const numberTarget=[0,1,2,3,4,5,6,7,8,9];
    let count=0;
    numberTarget.forEach(number=>{
        if(!numberSet.has(number)) count+=number;
    });
    return count;
}

0부터 9까지의 기준 배열을 순회하면서
Set 구조로 변환한 numbers 에 has() 함수를 이용해서 체크하였다.

💚 재귀와 임의배열

이 코드가 제일 놀라웠는데,

어떠한 수를 3진법 형식으로 변환하는데, 123 이 아니라 124의 형태로 표기하는 것이었다.

출처는 124 나라의 숫자 in 연습문제 였는데, 어떤 분이 재귀식과 임의 배열을 이용하여 풀이하였다.

추천 수가 많았던 신기한 코드

function solution(n) {
    return n===0 ? '' : solution(parseInt((n-1)/3)) + [1, 2, 4][(n-1)%3];
}

내가 제출한 코드

const translateMap=new Map();
translateMap.set(1,"1");
translateMap.set(2,"2");
translateMap.set(0,"4");

/** 124 나라는 (0을 제외하고 본다면) 3진법 표기를 따르고 있습니다.

    단 123 에 대하여 124 로 표기하고 있습니다.
    따라서 나머지가 3보다 작게 나올 때까지 3으로 나눈 후
    자릿수에 대응되는 124 를 곱해서 이를 전부 합산하면 결과물이 나옵니다.
*/
function solution(n) {
    let number=n;
    let result="";
    while(number!==0) {
        const reduce=number%3;
        result=translateMap.get(reduce) + result;

        number=(reduce===0) ? number-3 : number-reduce;

        number=number/3;
    }

    return result;
}
profile
2022년 12월 9일 부터 노션 페이지에서 작성을 이어가고 있습니다.

0개의 댓글