배열 Array 레스꼬
객체보다 배열을 쓰는게 효율적인 상황 :
1) property name 보다는 값들의 순서가 중요할 때
ex. 순위목록, 시리즈 순서, 십이간지, ... 또는 어떤 집합 (좋아하는 과일 등)
... 사실 배열도 객체임
let 배열이름 = [
요소1 (element),
요소 2,
...,
요소 n
];
... 파이썬 리스트랑 같은 형태네..? = 그것도 배열이니까..
대괄호를 쓴다
index 순서 가 매겨짐
indexing ~ 0부터 시작
console.log(배열이름[index])
<배열 값 출력하기>
let dataType = ['number', 'string', 'boolean', 'null', 'undefined', 'object'];
// 1번째 풀이
for (let i of dataType){
console.log(i);
}
// 2번째 풀이
for (let i = 0; i < 6; i++){
console.log(dataType[i]);
}
배열에서 쓸수있는 내장?메소드
dateType.length -> 배열 안의 요소의 개수
dateType[dateType.length] 로도 쓸수 있음
dateType[dateType.length - 1] 등으로 index 쓸수있음
요소 추가/수정하기
배열이름[index] = ' 값 ' ;
length 를 뛰어넘은 값을 넣어서 배열의 요소를 추가하면 중간에 빈 값(empty)가 생김
요소 삭제하기 + 수정/추가하기
(x) delete 배열이름[index]; // => empty 로 남아있음, 요소 개수도 유지
(o) 배열이름.splice(startIndex, deleteCount, item) 메소드 사용하기
dateType.splice(4); // 4번 index 부터 뒤의 모든 요소 삭제됨
dateType.splice(출발index, 삭제할 개수, 삭제된 자리에 추가할 item);
dateType.splice(, 삭제할 개수, 삭제된 자리에 추가할 item);
dateType.splice(dataType.length, 0, 삭제된 자리에 추가할 item); // 배열 맨 끝자리에 0개를 삭제, item 추가
deleteCount = 0으로 넣어주면 그 자리에 값 추가할 수 있다
deleteCount = 1으로 넣어주면 해당 요소를 수정할수있다
let celsiusTemps = [27, 25, 26, 22, 28, 27, 21];
let fahrenheitTemps = [];
for (let i = 0; i < celsiusTemps.length; i++){ //대괄호 쓰는건 index 불러오는 방법ㅇㅣ래..
// 첫번째 풀이
let F = ( celsiusTemps[i] * 9 / 5 ) + 32;
fahrenheitTemps[i] = F;
// 강의풀이
fahrenheitTemps[i] = ( celsiusTemps[i] * 9 / 5 ) + 32; // 바로 넣으면 됨
}
console.log(fahrenheitTemps);
let fruits = ['레몬', '토마토', '딸기', '바나나'];
let ages = [20, 24, 25, 29, 30, 33];
let numbers = [];
// fruits 배열에 '토마토'를 삭제하고 그 자리에 '사과', '청포도' 를 추가해 주세요
fruits.splice(1,1, '사과', '청포도')
// fruits 배열의 첫 번째 요소를 삭제해 주세요
fruits.splice(0,1)
// ages 배열에 마지막 요소를 삭제해 주세요
ages.splice(ages.length - 1,1)
// ages 배열의 2번, 3번 인덱스를 26, 28로 변경해 주세요
ages.splice(2, 2, 26, 28)
// numbers 배열에 1, 2, 3, 5, 8, 9를 순서대로 추가해 주세요
numbers.splice(numbers[numbers.length],0, 1, 2, 3, 5, 8, 9)
// 반복문을 활용해서 numbers 배열의 요소들 중 홀수를 모두 삭제해 주세요
for (let i = numbers.length - 1; i >= 0; i--){ // 반복문이 실행됨에 따라 배열 개수가 줄어들기때문에 역순으로 실행해야한다
if (numbers[i] % 2 !== 0){
numbers.splice(i, 1)
}
}
- numbers.length:
- 배열의 길이를 나타내는 속성입니다.
- 배열에 포함된 요소의 개수를 반환합니다.
- 주로 배열의 길이를 알고자 할 때, 반복문에서 사용됩니다.
- numbers[numbers.length]:
- 배열의 현재 길이를 인덱스로 사용하여 배열의 요소에 접근하려는 시도입니다.
- 현재 배열의 마지막 요소 다음 위치를 나타냅니다.
- 배열의 끝에 새로운 요소를 추가할 때 사용될 수 있습니다.
- numbers[numbers.length-1]: => 마지막 요소에 접근
splice..이어서
1. 배열의 메소드
1) 첫번째 요소 삭제 #파라미터를 받지않는 메소드
배열이름.shift();
2) 마지막 요소 삭제 #파라미터를 받지않는 메소드
배열이름.pop();
3) 배열 첫 요소로 값 추가
배열이름.unshift(value);
4) 배열 마지막 요소로 값 추가
배열이름.push(value);
배열 양 끝에 접근할때는 splice보다 각 메소드를 사용하는게 코드 간결
5) 특정 값 찾기
배열이름.indexOf(item);
배열에 item이 포함되어있으면 인덱스가 리턴됨
포함되어있지 않으면 -1 리턴됨
여러번 포함되어있으면 처음 발견된 인덱스가 리턴됨
배열이름.lastIndexOf(item);
마지막 인덱스부터 탐색 (인덱스는 여전히 앞에서부터 0,1,2...)
배열이름.includes(item);
포함 여부 확인 true/false
6) 배열 뒤집기
배열이름.reverse();
* 배열 또는 변수를 선언할때는 let, var, const 를 꼭 사용하도록 하자
let arr = [1,2,3,4,5] ; 배열을 선언
2. for ... of 반복문
for ( let element of arr) {
console.log(element);
}
// 요소 of 배열이 들어감
비교) for ... in 반복문
for (let index in arr) {
console.log(arr[index]);
}
// 프로퍼티네임 in 객체가 할당됨
배열도 '객체'니까 ▷ 인덱스 in 배열
=> 배열의 요소를 출력하기 위해 for in 반복문을 쓰는건 비권장
(단순 열거 라고 생각하면 될듯? 순서가 달라질수 있음 & 예상치못한 속성이 포함될 수 있다)
비교) for 반복문
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// 똑같이 index로 배열의 요소를 출력하지만 반복문의 초기값, 조건, 증감식을 명시하고
배열 요소를 순차적으로 접근하므로 순서를 보장한다.
헷갈리는 지점~!
Q. 객체의 프로퍼티 vs 배열의 요소 ?
비교 | Properties of Objects | Elements of Arrays |
데이터 저장 형태 |
키key -값 value 쌍 (property name - property value) 중괄호 |
인덱스 기반 Index-based 대괄호 |
키는 문자열 또는 심볼 값은 어떤 타입이든 가능하다 |
인덱스는 0부터 시작, 요소들은 배열에 순서대로 저장된다 |
|
예시문 |
let person = { name : "Alice", age : 30 }; |
let numbers = [10, 20, 30]; |
접근 방법 |
점표기법, 대괄호 표기법 console.log(person.name); console.log(person["age"]); |
대괄호 표기법 console.log(numbers[0]); console.log(numbers[1]); |
특징 |
순서가 없음 서로 다른 타입의 데이터 그룹을 만들때 유용 |
요소들이 추가된 순서대로 유지됨 동일한 타입의 데이터 그룹을 만들때 |
▼ 투표 집계 예제 .. 배열과 객체가 헷갈리는 나에게 딱맞는 예제네 ^-^
(내 풀이)
(모범 답안)
// 투표 결과 리스트 = 배열
let votes = [
'이재식', '이재식', '이규하', '이규하', '이규하',
'이재식', '이재식', '이규하', '이규하', '이재식',
'이규하', '이규하', '이규하', '이규하', '이재식',
'이재식', '이규하', '이재식', '이재식', '이재식',
'이재식', '이재식', '이규하', '이규하', '이규하',
'이규하', '이규하', '이재식', '이규하', '이규하',
'이규하', '이규하', '이재식', '이규하', '이규하',
'이규하', '이재식', '이재식', '이재식', '이규하',
];
// 후보별 득표수 객체
let voteCounter = {};
voteCounter['이재식'] = 0;
voteCounter['이규하'] = 0;
// for 문 밖에서 초기화해줘야함
// votes 배열을 이용해서 voteCounter 객체를 정리하기
for (let name of votes) { // for of문을 이용해서votes에 있는 후보 이름을 순서대로name이라는 변수에 지정되면,
// 이름별로 count 증가? 시켜서 voteCounter에 저장 시켜야댐
// 객체에 키 : 값 쌍을 추가하기
if (name === '이재식'){
voteCounter['이재식'] += 1;
} else {
voteCounter['이규하'] += 1;
}
// name을 voteCounter 객체에 반영
if (name in voteCounter) { // in 연산자를 통해 프로퍼티 존재 여부 확인
voteCounter[name] += 1; // 이름이 있으면 +1을 더하고
} else{
voteCounter[name] = 1; // 없으면 1로 만들어준다 (즉 0에서 +1)
}
}
// 후보별 득표수 출력
console.log(voteCounter);
2. 다차원 배열 multidimensional array : 배열안에 배열
2차원 배열
let twoDimensional = [[1,2], [3,4]];
...
1) 요소에 접근하기
console.log(twoDimensional[0]); // [1, 2]
console.log(twoDimensional[0][1]); 2
2) 값들의 위치나 순서가 중요할때 / 의미는 중요하지 않을때 -> 다차원 배열 사용
값들의 위치나 순서 & 의미까지 중요 -> 객체 사용 (key 값으로 구분)
▼팀나누기 예제
//2차원 배열
let groups = [
['영준', '캡틴'],
['태순', '우재'],
['재훈', '지웅'],
['윤형', '동욱'],
['규식', '소원'],
]; // [이긴사람 0번, 진사람 1번]
//2차원 배열
let teams = [
[],
[],
];
// groups [i][0] = 이긴사람 / i 0부터 i ++
// groups [j][1] = 진사람
for (let i = 0; i < groups.length; i++){
teams[0].push(groups[i][0]);
}
for (let j = 0; j < groups.length; j++){
teams[1].push(groups[j][1]);
}
// 강의 풀이
for(let i = 0; i < groups.length; i++) {
for(let j = 0; j < groups[i].length; j++) {
teams[j][i] = groups[i][j]; //결국은 이걸 도출해내는게 중요하다고 생각..
}
}
// 테스트 코드
console.log(teams[0]);
console.log(teams[1]);
//원하는 출력값
[ '영준', '태순', '재훈', '윤형', '규식' ]
[ '캡틴', '우재', '지웅', '동욱', '소원' ]
즉 행/열 바꾸기 코드인거네?
i 는 0 ~ 4 , j 는 0 ~ 1
[i] [j] -> [j] [i]
하나씩 써보면서 규칙을 찾는게 중요하겠다... 다짜고짜 반복문 때리지말고 ㅠ
여기까지가 배열..끗
자료형 심화 레스꼬
1. 지수 표기법
1000000000 = 1e9
e 앞에는 정수, 실수 다 들어올 수 있다
e 뒤에 -음수값이 들어가면 소수점 자리수 표시
2. 진법
1) 16진법 (hexadecimal) : 0 ~ 9 & A ~ F
0xff
2) 8진법 (Octal) : 0 ~ 7
0o377
3) 2진법(binary numal system) : 0 ~ 1
0b11111111
* 하나의 16진수는 4개의 2진수 숫자를 표시할 수 있다. F(16) = 1111(2)
두 개의 16진수는 8 bit, 즉 1 byte 를 표현할 수 있다. FF(16) = 11111111(2)
-> 컴퓨터에서 정보를 표현하기 유용..
3. 숫자형 메소드
숫자도 객체다 -> 메소드를 가지고 있음
1) toFixed (0~100) : 소수점 자릿수 고정
let myNumber = 0.1234;
console.log(myNumber.toFixed(3)); // 소수점 4번째 자리에서 반올림
console.log(myNumber.toFixed(7)); // 0으로 대체 : 0.1234000
=> 문자열로 반환 -> number()로 형변환 필요 또는 + 붙이면 number형으로 반환됨
2) toString (2~36) : 진법 변환
let myNumber = 255;
console.log(myNumber.toString(8));
=> 문자열로 반환
변수가 아닌 숫자를 바로 변환할땐 점. 두개를 써준다 or 괄호
console.log(255..toString(8));
console.log((255).toString(8));
4. Math 객체
Math.abs( ) : 절댓값
Math.max( ) :최댓값
Math.min( ) : 최솟값
Math.pow(x, y) : x의 y승 (거듭제곱)
Math.sqrt( ) : 제곱근
Math.round( ): 반올림 (→정수)
Math.floor( ):버림
Math.ceil(( ) :올림
Math.random( ) : 0이상 1미만 난수 // random 모듈을 import 하지 않아도 쓸수있다
ㄴ 10 미만의 정수값으로 얻고싶다면 Math.floor(Math.random() *10);
...
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Math
Math - JavaScript | MDN
Math 는 수학적인 상수와 함수를 위한 속성과 메서드를 가진 내장 객체입니다. 함수 객체가 아닙니다.
developer.mozilla.org
5. 숫자 계산 오류
컴퓨터는 어떤 소수를 2진수로 완벽하게 나타내지못하고 무한 소수로 나타내야함 .. 반올림 하면서 근소한 오차 발생
-> toFixed(1) & Number 처리 (또는 + 부호 붙이기) : 문자형 주의! \
또는 *10 & Math.round 로 정수 만들어주기 / 다시 나누기 10
6. 문자열 = 객체
let myString = 'Hi Codeit';
1) 요소 접근
console.log(myString[3]); //대괄호 표기법
console.log(myString.charAt(3)); //charAt 메소드
2) 문자열 길이
console.log(myString.length); length 프로퍼티 를 가지고 있다.
3) 요소 탐색 : 인덱스 반환
console.log(myString.indexOf('i'));
console.log(myString.lastIndexOf('i')); // -> 없으면 -1 반환
console.log(myString.indexOf('i', 'C')); // C 이후에 나오는 i의 인덱스를 반환
4) 대소문자 변환
myString.toUpperCase()
myString.toLowerCase()
5) 양끝 공백 제거
myString.trim()
6) 부분 문자열 접근 slice(start, end) 메소드 : end 파라미터 직전까지 리턴
myString.slice(0,2) : 0번부터 2 직전까지 (1까지)
myString.slice(3) : 3번부터 끝까지
myString.slice() : 0번부터 끝까지
7. data type
1) 기본형 primitive type : Number, String, Boolean, Null, Undefined
-> 변수에 그 값 자체가 담김
-> x = 5, y= x , y 값을 바꾸면 x 값은 그대로
2) 참조형 reference type : Object
-> 변수 주소값이 담김
-> x = { name : 'Code' }, y = x
y.birth = 2017; -> x에도 프로퍼티가 추가됨
{ name : 'Code' } 이라는 객체를 변수 x와 y 가 참조하므로 객체 값이 수정되면 x와 y 둘다 수정됨
배열도 객체이기때문에 same~
8. 참조형 data 복사하기
1) 배열 복사하기
let number1 = [1, 2, 3];
let number2 = number1; // number1의 배열을 참조하는 변수 선언
number2.push(4); //-> number1, number2 둘다 출력값이 변함
=> let number2 = number1.slice() // slice를 이용해서 그대로 값만 복사해온다
2) 객체 복사하기
let course1 = {
title : '기초'
language : 'python'
};
let course2= course1;
course2.title = '정석'
=> 출력했을때 둘다 값이 바뀌어있음
(방법1) Object 메소드 사용
let course2 = Object.assign({}, course1);
(방법2) for in a문 사용
let course2 = {} ; //빈 객체 생성
for (let key in course1){
course2[key] = course1[key];
}
(방법2 - 활용) 함수로 만들기
function cloneObject(object){
let temp = {};
for (let key in object){
temp[key] = object[key];
}
return temp;
}
let course2 = cloneObject(course1);
let course3 = cloneObject(course1);
* 복사하려는 객체/배열 안에 중첩해서 객체/배열이 있는 경우, 다시 주소값을 복사해서 참조하게 된다
9. 변수와 상수
코드 실행 중에 재할당되어야하는 경우 -> 변수 사용
그 외에 기본적으로 상수 const 를 사용한다
ex. 검색어 = 변수, 인거같지만 검색이 실행되는 순간 키워드는 변하지 않음 = 상수로 작용
참조형 데이터를 const 에 할당한 후 프로퍼티나 요소를 수정하더라도
주소값이 수정된 것은 아니기때문에 수정이 이루어진다.
단 다른 배열/객체를 재할당 할 수 없음! (에러발생)
10. var 변수 선언
특징 1) 중복 선언 허용 : 동일한 이름의 변수 선언 시 데이터 덮어쓰기가 됨
(let 을 사용하면 에러 발생함. 재할당이 가능한것과는 다름)
특징 2) 함수 scope : 중괄호 안에서 선언된 지역변수에 접근이 가능함 (블록 스코프를 무시 ?)
특징 3) 끌어올림 Hoisting : 뒤에서 변수를 선언해도 접근이 가능함
▼ 잔돈 계산기
function calculateChange(payment, cost) {
let change = payment - cost;
//let count_50000 = 0;
//let count_10000 = 0;
//let count_5000 = 0;
//let count_1000 = 0;
while (change > 0){
if(change >= 50000){쇼
change -= 50000;
count_50000 += 1;
} else if (change >= 10000){
change -= 10000;
count_10000 += 1;
} else if (change >= 5000){
change -= 5000;
count_5000 += 1;
} else if (change >= 1000) {
change -= 1000;
count_1000 += 1;
} else {
break;
}
}
console.log(`50000원 지폐: ${count_50000}장`);
console.log(`10000원 지폐: ${count_10000}장`);
console.log(`5000원 지폐: ${count_5000}장`);
console.log(`1000원 지폐: ${count_1000}장`);
}
[AI 코드]
function calculateChange(payment, cost) {
let change = payment - cost;
const type = [50000, 10000, 5000, 1000];
const count = [0, 0, 0, 0];
for (let i = 0; i < type.length; i++){
count[i] = Math.floor (change / type[i]);
change %= type[i];
}
const result = {};
for (let i = 0; i < type.length; i++){
result[`${type[i]}원 지폐`] = `${count[i]}장`;
}
for (const [key, value] of Object.entries(result)){
console.log(`${key}: ${value}`);
}
}
거슬러줘야하는 지폐의 장 수 ?
change = payment - cost;
(chage - (change % 50000)) / 50000;
잔돈을 5만원으로 나눈 나머지
를
잔돈에서 빼서
5만으로 나누면?
예를 들어 10만원으로 3만 3천원 결제할건데 그럼 67000원 받아야함. = change
67000원을 5만으로 나누면 나머지는 17000 원
을
67000원에서 빼면 50000원
을 5만원으로 나누면 1장~
하 .. 글쿠낭 ^ ^ 그렇네..
이걸 똑같이 쓸 수 있는게
Math.floor(change / 50000);
버림 메소드인데~ 이 코드인 즉슨.. 잔돈 67000원을 5만원으로 나누면 1. xx 나오는걸 1로 버린다는 뜻
그다음 change를 재할당해줘야한다
change = change - 50000 * count_5000 ;
또는 change %= 50000 ;
change = change % 50000 ; = 처음의 잔돈을 5만원으로 나눈 나머지
이거를 함수화해도되고, AI처럼 배열 + 반복문처리해도된다 이거겟지..
function billCounting(amount) { // amount 정수를 변수로 받는 함수
const count = (change - (change % amount)) / amount; // amount 지폐의 장 수 count
change = change - amount * count; // 계산된 잔돈 할당
return count;
}
const fiftyCount = billCounting(50000); // 각 지폐 count 에 위에서 계산한 count 반환
const tenCount = billCounting(10000);
const fiveCount = billCounting(5000);
const oneCount = billCounting(1000);
▼ 팰린드롬 (회문) 확인하기
function isPalindrome(word) {
// 여기에 코드를 작성하세요
// //풀이 1
for(let i = 0; i <= Math.floor(word.length / 2); i++){
let left = word[i];
let right = word[word.length - 1 - i];
if (left !== right){
return false;
}
}
return true;
}
// //테스트 코드
console.log(isPalindrome("racecar"));
console.log(isPalindrome("stars"));
console.log(isPalindrome("기러기"));
console.log(isPalindrome("123321"));
console.log(isPalindrome("hello"));
console.log(isPalindrome("kayak"));
나는 막.. 배열에 넣어가지구.. 뒤집어가지구.. 요소 하나씩 비교하고 그랫는데..(그마저도 ai가 처음 쓰는 메소드 쓰구..)
더 쉽게 푸는 방법이 있었던거시다.
'개발 공부 일지 > JavaScript' 카테고리의 다른 글
자바스크립트 - window (0) | 2024.07.15 |
---|---|
자바스크립트 - 이벤트 (0) | 2024.07.15 |
자바스크립트 - 태그 선택하기 (0) | 2024.07.15 |
코드잇 자바스크립트 (독학 10일차) (1) | 2024.06.12 |
코드잇 자바스크립트 (독학 9일차) (0) | 2024.06.11 |