지금 하는 작업은 하드 코딩에 가깝지만, 응용한다면 데이터를 가공하는데 도움이 될 것이라 생각한다.
// 데이터 가공해서 또 다른 Json 만들기 연습
// 학생, 학년, 학급, 학생 객체를 생성합니다.
let students = new Object();
let gradesX = new Object();
let classesX = new Object();
let studentX = new Array();
// 학생의 수만큼 k 변수로 반복문 돌립니다.
for(let k = 0; k<3; k++){
let name = "";
if( k%3 == 0 ){ name = "철수";
}else if(k%3 == 1){ name = "영희";
}else name = "동규";
let studentIndex = {
student_name : `${name}${k}`,
student_height : Math.floor( (Math.random() * 120) ) + k,
student_average : Math.floor( (Math.random() * 80) ) + k,
student_report : 0 + k
}
studentX.push(studentIndex);
} // k 변수 for문 종료
// classesX 객체에 key = student 에 value로 studentX 배열을 넣는다.
classesX.student = studentX;
// studentX 는 배열로 만들어둬서
/* classesX.student.description = "공부를 다들 열심히 합니다." */
// 와 같이 key, value를 추가할 수 없습니다.
// gradesX 객체에 key = class1 에 value로 바로 위의 classesX 객체를 넣는다. (객체 안에 객체 혹은 배열을 넣을 수 있다.)
gradesX.class1 = classesX;
// gradesX 객체에 key = class1 에 key가 teacher, 급훈인 value를 하나씩 넣는다. 우항은 string 값을 이용할 수 있어서 변수 혹은 for문 안에서도 가능하다.
gradesX.class1.teacher = "이민정쌤";
gradesX.class1.급훈 = "최선을 다하자";
// 위의 gradeX 객체를 students 객체의 key = grade1 의 value에 할당해준다.
students.grade1 = gradesX;
// 이외에 추가할만한 key, value를 할당해준다.
students.grade1.학주선생님 = "무서운 학주쌤";
// 아까 설정해둔 곳으로 접근해서 key, value 추가도 가능하다.
students.grade1.class1.특이사항 = "쉬는 시간엔 시끄럽지만 수업 때는 열심히 합니다.";
// 위와 비슷하게 학년 하나를 더 가공해봅니다.
// 원래라면 학생을 request로 얻어오던지 함수를 이용해서 다르게 하는게 맞지만 test를 위한 과정이라 같은 더미데이터를 사용하겠습니다.
let class2 = new Object();
class2 = classesX;
class2.teacher = "배용준쌤";
class2.급훈 = "잘생긴게 최고다";
students.grade1.class2 = class2;
students.description = "오지고 학생들";
console.log( JSON.stringify( students ) );
지금까지는 간단한 형식의 json 파일만 사용해서 잘 몰랐던 점들이 있었는데, 오늘 연습해보고 기록하면서 json에 좀 더 잘 알 수 있기를 !!!
배열만 이용한 json 만들기 연습
보통 이 경우는 이중 혹은 삼중, 그 이상의 배열을 다룰 때 쉽게 활용할 수 있다.
기본적으로 testArr[ i ][ j ][ k ] 이런 식으로 활용이 될 것이다.
예제 코드는 다음과 같다.
// 데이터 가공해서 또 다른 Json 만들기 연습
// Json 형식이 될 빈 리스트 생성
const student = new Array();
// 학년만큼 i 변수를 반복문 돌립니다.
for( let i = 0; i< 2; i++){
// 학년 배열 생성
let grades = new Array() ;
// 학급의 수 만큼 j 변수를 반복문 돌립니다.
for(let j = 0; j<4; j++){
// 학급 배열 생성
let classes = new Array() ;
// 학생의 수만큼 k 변수로 반복문 돌립니다.
for(let k = 0; k<3; k++){
// 학생 객체 생성
let students = new Object() ;
if( k%3 == 0 ){
students.student_name = `철수${i}${j}${k}`;
students.student_height = Math.floor( (Math.random() * 120) ) + k;
students.student_average = Math.floor( (Math.random() * 80) ) + k;
students.student_report = 0 + k;
}else if(k%3 == 1){
students.student_name = `영희${i}${j}${k}`;
students.student_height = Math.floor( (Math.random() * 120) ) + k;
students.student_average = Math.floor( (Math.random() * 80) ) + k;
students.student_report = 0 + k;
}else{
students.student_name = `동규${i}${j}${k}`;
students.student_height = Math.floor( (Math.random() * 120) ) + k;
students.student_average = Math.floor( (Math.random() * 80) ) + k;
students.student_report = 0 + k;
}
classes.push(students);
}
grades.push(classes);
}
student.push(grades);
}
// 전체 학생
console.log("전체 학생");
console.log( JSON.stringify( student ) );
// 한 학년의 학생
console.log("한 학년의 학생");
console.log( JSON.stringify( student[0] ) );
// 한 반의 학생
console.log("한 반의 학생");
console.log( JSON.stringify( student[0][0] ) );
// 한명의 학생
console.log("한명의 학생");
console.log( JSON.stringify( student[0][0][0] ) );
결과
전체 학생
student_make_json.js:44
[[[{"student_name":"철수000","student_height":14,"student_average":73,"student_report":0},{"student_name":"영희001","student_height":72,"student_average":9,"student_report":1},{"student_name":"동규002","student_height":119,"student_average":62,"student_report":2}],[{"student_name":"철수010","student_height":101,"student_average":10,"student_report":0},{"student_name":"영희011","student_height":81,"student_average":67,"student_report":1},{"student_name":"동규012","student_height":114,"student_average":43,"student_report":2}],[{"student_name":"철수020","student_height":17,"student_average":75,"student_report":0},{"student_name":"영희021","student_height":14,"student_average":75,"student_report":1},{"student_name":"동규022","student_height":111,"student_average":39,"student_report":2}],[{"student_name":"철수030","student_height":59,"student_average":44,"student_report":0},{"student_name":"영희031","student_height":59,"student_average":45,"student_report":1},{"student_name":"동규032","student_height":96,"student_average":25,"student_report":2}]],[[{"student_name":"철수100","student_height":104,"student_average":28,"student_report":0},{"student_name":"영희101","student_height":87,"student_average":70,"student_report":1},{"student_name":"동규102","student_height":39,"student_average":3,"student_report":2}],[{"student_name":"철수110","student_height":88,"student_average":47,"student_report":0},{"student_name":"영희111","student_height":42,"student_average":23,"student_report":1},{"student_name":"동규112","student_height":44,"student_average":6,"student_report":2}],[{"student_name":"철수120","student_height":102,"student_average":19,"student_report":0},{"student_name":"영희121","student_height":119,"student_average":41,"student_report":1},{"student_name":"동규122","student_height":83,"student_average":49,"student_report":2}],[{"student_name":"철수130","student_height":11,"student_average":15,"student_report":0},{"student_name":"영희131","student_height":97,"student_average":46,"student_report":1},{"student_name":"동규132","student_height":121,"student_average":71,"student_report":2}]]]
student_make_json.js:45
한 학년의 학생
student_make_json.js:48
[[{"student_name":"철수000","student_height":14,"student_average":73,"student_report":0},{"student_name":"영희001","student_height":72,"student_average":9,"student_report":1},{"student_name":"동규002","student_height":119,"student_average":62,"student_report":2}],[{"student_name":"철수010","student_height":101,"student_average":10,"student_report":0},{"student_name":"영희011","student_height":81,"student_average":67,"student_report":1},{"student_name":"동규012","student_height":114,"student_average":43,"student_report":2}],[{"student_name":"철수020","student_height":17,"student_average":75,"student_report":0},{"student_name":"영희021","student_height":14,"student_average":75,"student_report":1},{"student_name":"동규022","student_height":111,"student_average":39,"student_report":2}],[{"student_name":"철수030","student_height":59,"student_average":44,"student_report":0},{"student_name":"영희031","student_height":59,"student_average":45,"student_report":1},{"student_name":"동규032","student_height":96,"student_average":25,"student_report":2}]]
student_make_json.js:49
한 반의 학생
student_make_json.js:52
[{"student_name":"철수000","student_height":14,"student_average":73,"student_report":0},{"student_name":"영희001","student_height":72,"student_average":9,"student_report":1},{"student_name":"동규002","student_height":119,"student_average":62,"student_report":2}]
student_make_json.js:53
한명의 학생
student_make_json.js:56
{"student_name":"철수000","student_height":14,"student_average":73,"student_report":0}
기왕에 연습겸 만들어본거 헷갈리던 개념도 한번 시험해보았다.
Js에서 for of과 for in 구문의 차이점을 실제로 체감하기가 힘들었는데 오늘의 예제가 도움이 되었다.
// 1학년 1반의 모든 학생 출력
console.log("1학년 1반의 모든 학생 출력");
for( let i = 0; i < student[0][0].length; i++ ){
console.log( JSON.stringify( student[0][0][i] ) );
}
/** 결과
{"student_name":"철수000","student_height":49,"student_average":13,"student_report":0}
student_make_json.js:63
{"student_name":"영희001","student_height":97,"student_average":77,"student_report":1}
student_make_json.js:63
{"student_name":"동규002","student_height":88,"student_average":21,"student_report":2}
*/
// student[0][0] 을 변수화 시킨 후 1학년 1반의 모든 학생 출력
console.log("student[0][0] 을 변수화 시킨 후 1학년 1반의 모든 학생 출력");
let temp = student[0][0];
for( let i = 0; i < temp.length; i++ ){
console.log( JSON.stringify( temp[i] ) );
}
/** 결과
{"student_name":"철수000","student_height":49,"student_average":13,"student_report":0}
student_make_json.js:70
{"student_name":"영희001","student_height":97,"student_average":77,"student_report":1}
student_make_json.js:70
{"student_name":"동규002","student_height":88,"student_average":21,"student_report":2}
*/
// 반복문을 출력하는 여러가지 방법 중 하나, for of 구문
console.log("반복문을 출력하는 여러가지 방법 중 하나, for of 구문");
temp = student[0][0];
for( let item of temp ){
console.log( JSON.stringify( item ) );
console.log( item );
}
/** 결과
{"student_name":"철수000","student_height":49,"student_average":13,"student_report":0}
student_make_json.js:77
{student_name: '철수000', student_height: 49, student_average: 13, student_report: 0}
{"student_name":"영희001","student_height":97,"student_average":77,"student_report":1}
student_make_json.js:77
{student_name: '영희001', student_height: 97, student_average: 77, student_report: 1}
{"student_name":"동규002","student_height":88,"student_average":21,"student_report":2}
student_make_json.js:77
{student_name: '동규002', student_height: 88, student_average: 21, student_report: 2}
*/
// 반복문을 출력하는 여러가지 방법 중 하나, for in 구문
console.log("반복문을 출력하는 여러가지 방법 중 하나, for in 구문");
temp = student[0][0];
for( let item in temp ){
console.log( JSON.stringify( item ) );
console.log( item );
}
/** 결과
"0"
student_make_json.js:85
0
student_make_json.js:86
"1"
student_make_json.js:85
1
student_make_json.js:86
"2"
student_make_json.js:85
2
*/
이 외에도 맨 위에 동일한 작업이 반복되는 코드를 함수화 시켜서 할 수도 있습니다.
// 데이터 가공해서 또 다른 Json 만들기 연습
// Json 형식이 될 빈 리스트 생성
const student = new Array();
let makeStudentObject=( students, i, j, k )=>{
let name = "";
if( k%3 == 0 ){ name = "철수";
}else if(k%3 == 1){ name = "영희";
}else name = "동규";
students.student_name = `${name}${i}${j}${k}`;
students.student_height = Math.floor( (Math.random() * 120) ) + k;
students.student_average = Math.floor( (Math.random() * 80) ) + k;
students.student_report = 0 + k;
return students;
}
// 학년만큼 i 변수를 반복문 돌립니다.
for( let i = 0; i< 2; i++){
// 학년 배열 생성
let grades = new Array() ;
// 학급의 수 만큼 j 변수를 반복문 돌립니다.
for(let j = 0; j<4; j++){
// 학급 배열 생성
let classes = new Array() ;
// 학생의 수만큼 k 변수로 반복문 돌립니다.
for(let k = 0; k<3; k++){
classes.push( makeStudentObject( new Object() , i, j, k ));
}
grades.push(classes);
}
student.push(grades);
}
/** 결과
[[[{"student_name":"철수000","student_height":85,"student_average":79,"student_report":0},{"student_name":"영희001","student_height":46,"student_average":34,"student_report":1},{"student_name":"동규002","student_height":47,"student_average":18,"student_report":2}],[{"student_name":"철수010","student_height":118,"student_average":13,"student_report":0},{"student_name":"영희011","student_height":33,"student_average":28,"student_report":1},{"student_name":"동규012","student_height":95,"student_average":13,"student_report":2}],[{"student_name":"철수020","student_height":53,"student_average":6,"student_report":0},{"student_name":"영희021","student_height":26,"student_average":80,"student_report":1},{"student_name":"동규022","student_height":112,"student_average":59,"student_report":2}],[{"student_name":"철수030","student_height":71,"student_average":64,"student_report":0},{"student_name":"영희031","student_height":69,"student_average":23,"student_report":1},{"student_name":"동규032","student_height":74,"student_average":24,"student_report":2}]],[[{"student_name":"철수100","student_height":47,"student_average":30,"student_report":0},{"student_name":"영희101","student_height":36,"student_average":66,"student_report":1},{"student_name":"동규102","student_height":109,"student_average":21,"student_report":2}],[{"student_name":"철수110","student_height":39,"student_average":71,"student_report":0},{"student_name":"영희111","student_height":104,"student_average":17,"student_report":1},{"student_name":"동규112","student_height":102,"student_average":41,"student_report":2}],[{"student_name":"철수120","student_height":57,"student_average":29,"student_report":0},{"student_name":"영희121","student_height":22,"student_average":15,"student_report":1},{"student_name":"동규122","student_height":35,"student_average":15,"student_report":2}],[{"student_name":"철수130","student_height":30,"student_average":72,"student_report":0},{"student_name":"영희131","student_height":111,"student_average":41,"student_report":1},{"student_name":"동규132","student_height":105,"student_average":70,"student_report":2}]]]
*/
※ 이 코드는 정답이 아니고, 집단지성의 힘을 빌려 재구성한 코드입니다! 이와 같은 방식을 구현하는 방법은 많습니다.
/**
* scrollAnimation 설명서
* 이 메서드는 화면(window)의 스크롤에 맞춰 특정 요소에
* 이벤트(show, hide, transform) 를 줄 수 있습니다.
* 제이쿼리 임포트를 필수로 요구합니다.
* show_and_hide 클래스를 이벤트를 적용할 오브젝트에 적용하면 됩니다.
* _checkPosition에 add, remove에 있는 클래스는 자기 상황에 맞게 바꾸면 됩니다.
*/
const scrollAnimation=()=>{
// items는 나중에 querySelectorAll을 사용할 때 쓸 수 있습니다
// actionHeight는 가로 길이로 얼마나 스크롤했을 때 이벤트가 발동할지
let items, actionHeight;
// 페이지가 로드될 때 아이템에 쿼리셀렉터를 실행하고
// actionHeight
const initModule=()=>{
items = document.querySelectorAll(".show_and_hide");
actionHeight = 600;
_addEventHandlers();
};
const _addEventHandlers=()=>{
window.addEventListener("scroll", _checkPosition);
window.addEventListener("load", _checkPosition);
window.addEventListener("resize", initModule);
};
const _checkPosition=()=>{
// 현재 윈도우의 스크롤 위치를 변수화 시킵니다.
let here = window.scrollY;
// if 조건일 때 사라지게 하고
if(here>actionHeight){
$('.show_and_hide').removeClass('show').addClass('hide');
}else{
// else 조건일 때 보여지게 하는 코드입니다.
$('.show_and_hide').removeClass('hide').addClass('show');
}
}
return {
init: initModule
}
}
// 함수 초기화를 시켜줍니다.
scrollAnimation().init();
밑에 부분에서는 쿼리셀렉터를 이용한 구문이 없지만 원래 코드에서 쓰던 구조를 변형해서 제이쿼리로 특정 분기를 잡아서 클래스를 주고 사라지게 하는 방식을 채택했습니다.
아니면 그냥 vscode 등의 편집기나 다른 ide에서 클론한 프로젝트에서 직접 .gitignore라는 파일을 만들어도 무방하다.
.gitignore(깃 이그노어) 작성하기
.gitignore를 작성하는 첫번째 방법으로는 파일 이름을 직접 적는 방법이 있다.
예를 들자면 "readme.md", "index.html" 등처럼 직접적인 파일 이름을 명시하는 행위를 말한다.
이렇게 하면 깃은 해당 이름을 한 파일을 더 이상 추적하지 않는다.
자주 gitignore에 넣는 단일 파일들로는 환경변수 설정 파일들이 있다. (.env부터 해서 블라블라블라)
root 경로에 있는 파일이 아니라면 그 파일의 경로를 전부 적어줘야한다.
루트에 views가 있고 파일들과 폴더들이 있는 상황
이런 구조에서 잠시 어떤 이슈가 생겨 advertisement.html을 깃으로 업데이트하지 않기를 원한다면 깃이그노어에
views/advertisement.html
이라고 한줄 추가해주면 깃은 더 이상 이 파일을 추적하지 않게 된다.
엄밀히 말해서 이 경우는 저 파일이 이미 커밋되어서 Repository까지 올라가있던 경우라면 깃에서 저 파일을 삭제한 후
깃 이그노어에 views/advertisement.html 를 저장해야지 제대로 적용이 되는 것을 확인할 수 있다.
경로의 시작이 root인 이유는 보통 .gitignore도 root에 있기 때문인데 파일의 경로는 .gitignore의 위치를 기준으로 깃이 판단하는 모양이다.
두번째 방법으로는 경로를 지정하는 방법이 있다. (이 문제 때문에 오늘의 포스팅이 있게 되었다.)
형식은 "경로 이름/" 의 모양을 한다.
node.js를 이용한 프로젝트를 혼자서 진행하고 있었는데, 깃에 백업을 하려니 파일의 갯수가 너무나도 많아서 다 푸쉬를 하는게 맞는지 찾아보게 되었다. 알고보니 노드의 modules은 그때그때 npm install을 이용해서 진행하는 것이 간편하다. 그래서 혼자서 할 때 뿐만 아니라 협업할 때에도 "node_modules/" 를 .gitignore에 추가하는 편이 좋다.
경로를 포함한 파일을 깃 이그노어에 추가할 때 추가적으로 알아두면 좋은게 있는데,
routes/**/controller.js 와 같은 식으로 깃 이그노어를 작성한다면 이 문장은
routes/controller.js routes/front-end/public/controller.js 혹은 이것보다 더 짧거나 긴 디렉토리라도 루트 경로에 있는 파일이 2개의 애스터리스크 전에 경로와 겹치고 뒤의 파일 이름이 같다면 깃은 같은 조건의 파일을 전부 추적하지 않게 됩니다.
비슷하게
public/css/**
이런 식으로 작성하게 되면 public/css/ 밑의 파일들은 전부 깃 추적에서 제외됩니다.
세번째 방법으로는 확장자를 지정하는 방법이 있다.
형식은 " *.확장자이름 " 의 모습을 한다.
예를 들자면 *.log 를 깃이그노어에 추가한다면 .log 확장자 파일은 더 이상 깃이 추적하지 않게 된다.
.gitignore.io 이용하기
.gitignore.io란 프로젝트를 진행할 때 사용할 환경, 언어 등을 세팅해주면
깃 이그노어에 세팅할 문서를 만들어주는 사이트입니다.
아래의 사진은 이 사이트에 "node" 라는 키워드 하나만 넣었을 때 나오는 요소들 중에서