-
문자열을 배열로 변환, 배열을 문자열로 변환, Spread OperatorLanguage/JavaScript 2022. 9. 22. 16:30
1. 문자열을 배열로 변환
-출처 : https://codechacha.com/ko/javascript-convert-string-to-array/
// 예제 // 변수 myString에 담긴 문자열 'JavaScript'를 배열로 반환하라. const myString = 'JavaScript' /* 단어(str 인자)가 주어졌을 때 함수의 리턴값은 주어진 단어를 구성하는 모든 문자를 담고 있는 배열입니다. 만약 빈 문자열이 주어졌다면, 빈 배열을 반환해야 합니다. 결과값 : let output = getAllLetters(myString); console.log(output); --> ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't'] */
1.1 string.charAt() 메소드
.charAt() 함수는 문자열에서 특정 인덱스에 위치하는 유니코드 단일문자를 반환합니다.
str.charAt(index) //매개변수 : index, 0과 문자열의 길이 - 1 사이의 정수값. //인자를 생략하면 기본값으로 0를 설정되고 첫 문자를 반환한다. //반환 값 : 지정된 인덱스에 해당하는 유니코드 단일문자를 반환한다. //만약 인덱스가 문자열 길이보다 큰 경우 빈 문자열 (예) " " 을 반환한다.
//해결 function getAllLetters(str) { let strArray = []; for (let i = 0; i < str.length; i++) { strArray.push(str.charAt(i)) } return strArray; } console.log(getAllLetters(myString)); //['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']
1.2 string.split() 메소드 : 구분자로 문자열을 분리하여 배열로 변환
split() 메서드는 String 객체를 지정한 구분자를 이용하여 여러 개의 문자열로 나눕니다.
split() split(separator) split(separator, limit) /* [매개변수] - separator(선택) : 원본 문자열을 끊어야 할 부분을 나타내는 문자열을 나타냅니다. 실제 문자열이나 정규표현식을 받을 수 있습니다. 문자열 유형의 separator가 두 글자 이상일 경우 그 부분 문자열 전체가 일치해야 끊어집니다. separator가 생략되거나 str에 등장하지 않을 경우, 반환되는 배열은 원본 문자열을 유일한 원소로 가집니다. separator가 빈 문자열일 경우 str의 각각의 문자가 배열의 원소 하나씩으로 변환됩니다. - limit(선택) : 끊어진 문자열의 최대 개수를 나타내는 정수입니다. 이 매개변수를 전달하면 split() 메서드는 주어진 separator가 등장할 때마다 문자열을 끊지만 배열의 원소가 limit개가 되면 멈춥니다. 지정된 한계에 도달하기 전에 문자열의 끝까지 탐색했을 경우 limit개 미만의 원소가 있을 수도 있습니다. 남은 문자열은 새로운 배열에 포함되지 않습니다. [반환값] 주어진 문자열을 separator마다 끊은 부분 문자열을 담은 Array. */
//해결 let myString = 'JavaScript' function getAllLetters(str) { return str.split('') } console.log(getAllLetters(myString)); //['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']
mozilla에서 split 메소드에 구분자를 빈 문자열 ('')로 하면 어떤 문제가 발생한다고 해서 이 방법은 안 쓰는 것이 좋을 것 같긴 하다. 근데 그 문제가 어떤 문제인지 이해가 어렵네...? 그 문제를 확인할 수 있는 것은 stack overflow의 'How do you get a string to a character array in JavaScript?' 이다. 여기서 문제되는 상황은 아래와 같다.
주의: 구분자로 빈 문자열("")을 제공하면, 사용자가 인식하는 문자 하나(grapheme cluster) 또는 유니코드 문자(코드포인트) 하나씩으로 나누는 것이 아니라, UTF-16 코드유닛으로 나누게 되며 써로게이트 페어가 망가질 수 있습니다. 스택 오버플로우의 How do you get a string to a character array in JavaScript? 질문도 참고해 보세요.
- 출처 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/split// DO NOT USE THIS! const a = '𝟘𝟙𝟚𝟛'.split(''); console.log(a); // Output: ["�","�","�","�","�","�","�","�"] // This is not unicode compliant. //"I💖U".split('') results in the 4 character array ["I", "�", "�", "u"] //which can lead to dangerous bugs. const b = 'I💖U'.split(''); console.log(b); // Output: ["I", "�", "�", "U"]
1.3 Array.from() 메소드 : 문자열의 문자들을 분리하여 배열로 변환
Array.from() 메서드는 유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.
Array.from(arrayLike[, mapFn[, thisArg]]) /* [매개변수] - arrayLike : 배열로 변환하고자 하는유사 배열 객체나 반복 가능한 객체. - mapFnOptional(생략): 배열의 모든 요소에 대해 호출할 맵핑 함수. - thisArgOptional(생략) : mapFn 실행 시에 this로 사용할 값. [반환 값] 새로운 Array 인스턴스. */
//해결 let myString = 'JavaScript' function getAllLetters(str) { let myArray = []; myArray = Array.from(str); } console.log(getAllLetters(myString)); //['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']
1.4 Spread Operator (스프레드 연산자) : 문자열의 문자들을 분리하여 배열로 변환
- 출처 : https://paperblock.tistory.com/62
스프레드 연산자를 사용하면 배열, 문자열, 객체 등 반복 가능한 객체 (Iterable Object)를 개별 요소로 분리할 수 있습니다. 사실 말로 표현하면 의미적으로는 크게 와 닿지 않죠? 저도 말하면서 저게 맞는 말인지 고민이 됩니다.
(자세한 내용은 하단 3. 스프레드 연산자 참고)
// Array var arr1 = [1, 2, 3, 4, 5]; var arr2 = [...arr1, 6, 7, 8, 9]; console.log(arr2); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] // String var str1 = 'paper block'; var str2 = [...str1]; console.log(str2); // [ "p", "a", "p", "e", "r", " ", "b", "l", "o", "c", "k" ]
//해결 let myString = 'JavaScript' function getAllLetters(str) { let myArray = []; return myArray = [...str]; } console.log(getAllLetters(myString)); //['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']
2. 배열을 문자열로 변환
- 출처 : https://codechacha.com/ko/javascript-array-to-string/
2.1 arr.join() 메소드
join() 메서드는 배열의 모든 요소를 연결해 하나의 문자열로 만듭니다.
arr.join([separator]) /* [매개변수] - separator(생략) : 배열의 각 요소를 구분할 문자열을 지정합니다. 이 구분자는 필요한 경우 문자열로 변환됩니다. 생략하면 배열의 요소들이 쉼표로 구분됩니다. separator가 빈 문자열이면 모든 요소들이 사이에 아무 문자도 없이 연결됩니다. [반환 값] 배열의 모든 요소들을 연결한 하나의 문자열을 반환합니다. 만약 arr.length 가 0이라면, 빈 문자열을 반환합니다. [설명] 모든 배열 요소가 문자열로 변환된 다음 하나의 문자열로 연결됩니다. [경고] 요소가 undefined 또는 null이면 빈 문자열로 변환합니다. */ const elements = ['Fire', 'Air', 'Water']; console.log(elements.join()); // expected output: "Fire,Air,Water" console.log(elements.join('')); // expected output: "FireAirWater" console.log(elements.join('-')); // expected output: "Fire-Air-Water"
//해결 let myArray = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't'] function getString(arr) { let myString ; return arr.join('') } console.log(getString(myArray)); //'Javascript'
2.2 for 반복문
2.2.1 for loop
//해결 1 let myArray1 = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't'] let myString1 = ''; for (let i = 0; i < myArray1.length; i++) { myString1 = myString1 + myArray1[i] } console.log(myString1); //'Javascript'
2.2.2 arr.forEach() 메소드
forEach() 메서드는 주어진 함수를 배열 요소 각각에 대해 실행합니다.
arr.forEach(callback(currentvalue[, index[, array]])[, thisArg]) /* [매개변수] - callback : 각 요소에 대해 실행할 함수. 다음 세 가지 매개변수를 받습니다. currentValue : 처리할 현재 요소. index : 처리할 현재 요소의 인덱스.< array : forEach()를 호출한 배열. - thisArg : callback을 실행할 때 this로 사용할 값. [반환 값] undefined. [설명] forEach()는 주어진 callback을 배열에 있는 각 요소에 대해 오름차순으로 한 번씩 실행합니다. 삭제했거나 초기화하지 않은 인덱스 속성에 대해서는 실행하지 않습니다. (예: 희소 배열) */
//해결 2 let myArray2 = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't'] let myString2 = ''; myArray2.forEach((el) => myString2 = myString2 + el) console.log(myString2); //'Javascript'
2.3 arr.toString(), str.replace 메소드
- arr.toString()
toString() 메서드는 지정된 배열 및 그 요소를 나타내는 문자열을 반환합니다.
- str.replace()
replace() 메서드는 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환합니다. 그 패턴은 문자열이나 정규식(RegExp)이 될 수 있으며, 교체 문자열은 문자열이나 모든 매치에 대해서 호출된 함수일 수 있습니다.
pattern이 문자열 인 경우, 첫 번째 문자열만 치환이 되며 원래 문자열은 변경되지 않습니다.
arr.toString() //arr.toString() 메서드는 지정된 배열 및 그 요소를 나타내는 문자열을 반환합니다. str.replace() var newStr = str.replace(regexp|substr, newSubstr|function) /* [매개변수] - regexp (pattern) : 정규식(RegExp) 객체 또는 리터럴. 일치하는 항목은 newSubStr 또는 지정된 함수(function)가 반환 한 값으로 대체됩니다. - substr (pattern) : newSubStr로 대체 될 String. 정규식이 아닌 글자 그대로의 문자열로 처리됩니다. 오직 첫 번째 일치되는 문자열만이 교체됩니다. - newSubStr (replacement) : 첫번째 파라미터를 대신할 문자열(String). 여러가지 대체 패턴들이 지원됩니다. 아래의 "매개변수가 string으로 지정되었을 때" 섹션을 참고하세요. - function (replacement) :주어진 regexp 또는 substr에 일치하는 요소를 대체하는 데 사용될 새 하위 문자열을 생성하기 위해 호출되는 함수. 이 함수에 제공되는 인수는 아래 "매개변수가 function으로 지정되었을 때"단원에서 설명합니다. [반환값] 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열 */
//해결 2 let myArray = ['J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't'] let myString = myArray.toString(); console.log(myString); //'J,a,v,a,S,c,r,i,p,t' -> 알파벳 사이의 (,)를 제거해야한다. myString = myString.replace(/,/g, ""); console.log(myString); //'Javascript'
replace 메서드를 쓰려면 정규식을 알아야한다.... 그래서 이건 정규식 배우기 전까지는 쓰기 좀 어려울듯.
3. Spread Operator( ... , 스프레드 연산자)
- 출처 : https://paperblock.tistory.com/62
스프레드 연산자를 사용하면 배열, 문자열, 객체 등 반복 가능한 객체 (Iterable Object)를 개별 요소로 분리할 수 있습니다. 사실 말로 표현하면 의미적으로는 크게 와닿지 않죠? 저도 말하면서 저게 맞는 말인지 고민이 됩니다.
// 예제 var arr1 = ['a', 'b', 3, 4, 5]; var arr2 = [...arr1]; // arr->arr var obj1 = {...arr1}; // arr->obj console.log(arr2); // ["a", "b", 3, 4, 5] console.log(obj1); /* { 0: 'a', 1: 'b', 2: 3, 3: 4, 4: 5 } */ var str1 = 'JavaScript'; var arr3 = [...str1]; // str->arr var obj2 = {...str1}; // str->obj console.log(arr3); //["J", "a", "v", "a", "S", "c", "r", "i", "p", "t"] console.log(obj2); /* { 0: "J", 1: "a", 2: "v", 3: "a", 4: "S", 5: "c", 6: "r", 7: "i", 8: "p", 9: "t" } */
3.1 배열 병합(Array Concatenation)
기존에 두 개의 배열을 결합하는 concat 메서드를 배웠다.
ES6에서는 spread 연산자를 활용하여 다양한 형태의 배열 병합이 가능하다.
// 기존 방식 var arr1 = [1,2,3]; var arr2 = [4,5,6]; var arr = arr1.concat(arr2); console.log(arr); // [ 1, 2, 3, 4, 5, 6 ] // ES6 spread operator var arr1 = [1,2,3]; var arr2 = [4,5,6]; var arr = [...arr1, ...arr2]; console.log(arr); // [ 1, 2, 3, 4, 5, 6 ] // 다양한 형태의 배열 병합 var arr1 = [1,2,3]; var arr2 = [4,5,6]; arr1.push(...arr2) console.log(arr1); // [1,2,3,4,5,6] var arr1 = [1,2]; var arr2 = [0, ...arr1, 3, 4]; console.log(arr2); // [0, 1, 2, 3, 4]
3.2 배열 복사(Copying Arrays)
JS에서 배열을 새로운 변수에 할당(=)하는 경우 변수에 할당된 새로운 배열은 기존 배열을 참조한다.
이것과 관련된 설명은 다음 글을 참고하라.
이 말은, 참조된 배열을 변경하는 경우 원본 배열이 변경된다는 의미이다.
// 단순 변수 할당 var arr1 = ['철수','영희']; var arr2 = arr1; arr2.push('바둑이'); console.log(arr2); // [ "철수", "영희", "바둑이" ] // 원본 배열도 변경됩니다. console.log(arr1); // [ "철수", "영희", "바둑이" ]
그런데, 참조하지 않고 배열 안의 값을 복사해야 할 수도 있다. 이때는 어떻게 할까?
기존의 slice 메소드나 ES5의 map 메소드를 이용했다고 한다.
두 메소드의 느낌이, 배열 안의 각각 요소에 접근하는 메소드이니까 요소 값(value)을 복사하는 것이 가능하겠단 생각이 든다!
// Javascript array 복사 var arr1 = ['철수','영희']; var arr2 = arr1.slice(); arr2.push('바둑이'); console.log(arr2); // [ "철수", "영희", "바둑이" ] // 원본 배열은 변경되지 않습니다. console.log(arr1); // [ "철수", "영희" ] // ES5 map var arr1 = ['철수','영희']; var arr2 = arr1.map((item) => item); arr2.push('바둑이'); console.log(arr2); // [ "철수", "영희", "바둑이" ] // 원본 배열은 변경되지 않습니다. console.log(arr1); // [ "철수", "영희" ]
그런데, ES6에서는 spread 연산자를 사용하면 복사된 배열을 생성할 수 있다.
// ES6 spread operator var arr1 = ['철수','영희']; var arr2 = [...arr1]; arr2.push('바둑이'); console.log(arr2); // [ "철수", "영희", "바둑이" ] // 원본 배열은 변경되지 않습니다. console.log(arr1); // [ "철수", "영희" ]
참고로 Spread 연산자를 이용한 복사는 얕은(shallow) 복사를 수행하고, 배열 안에 객체가 있는 경우에는 객체 자체는 복사되지 않고 원본 값을 참조한다. 이것은 당연하지? 앞에서 설명한대로 값은 복사할 수 있지만 객체는 참조해야 하니까.
따라서 원본 배열 내의 객체의 값을 변경하는 경우 새로운 배열 내의 객체 값도 변경됩니다.
var arr1 = [{name: '철수', age: 10}]; var arr2 = [...arr1]; arr2[0].name = '영희'; console.log(arr1); // [ {name:'영희', age: 10}] console.log(arr2); // [ {name:'영희', age: 10}]
출처에 함수나 객체에서 쓰는 방법도 있는데 그건 나중에 학습하도록 한다! 필요할 때.
'Language > JavaScript' 카테고리의 다른 글
삼항연산자(조건부연산자, ?) (0) 2022.09.22 Value Types and Reference Types (0) 2022.09.22 단축 평가 값(short circuit evaluation) (0) 2022.09.05 JavaScript 세미콜론 가이드 (1) 2022.09.02 [JavaScript_codecademy] VARIABLES (0) 2022.09.01