Array HOF 연습 문제

Posted by Seongkyun Yu on 2020-03-23
Estimated Reading Time 12 Minutes
Words 2k In Total
Viewed Times

1. html 생성

아래 배열을 사용하여 html을 생성하는 함수를 작성하라.

creatHTML.js
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
const todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function render() {
let html = "";

todos.forEach(function (todo) {});

return html;
}

console.log(render());
/*
<li id="3">
<label><input type="checkbox">HTML</label>
</li>
<li id="2">
<label><input type="checkbox" checked>CSS</label>
</li>
<li id="1">
<label><input type="checkbox">Javascript</label>
</li>
*/

해답:

접기/펼치기 버튼
creatHTML.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function render() {
let html = "";

todos.forEach(function (todo) {
html += `<li id="${todo.id}">
<lable><input type="checkbox"${todo.completed ? " checked" : ""}>${
todo.content
}</label>
</li>
`;
});

return html;
}

console.log(render());
접기/펼치기 버튼
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { call, put, select, flush, delay } from "redux-saga/effects";
import { buffers, eventChannel } from "redux-saga";

// 소켓 만들기
const createSocket = () => {
const client = new W3CWebSocket("wss://api.upbit.com/websocket/v1");
client.binaryType = "arraybuffer";

return client;
};

// 소켓 연결용
const connectSocekt = (socket, connectType, action, buffer) => {
return eventChannel((emit) => {
socket.onopen = () => {
socket.send(
JSON.stringify([
{ ticket: "downbit-clone" },
{ type: connectType, codes: action.payload },
])
);
};

socket.onmessage = (evt) => {
const enc = new TextDecoder("utf-8");
const arr = new Uint8Array(evt.data);
const data = JSON.parse(enc.decode(arr));

emit(data);
};

socket.onerror = (evt) => {
emit(evt);
};

const unsubscribe = () => {
socket.close();
};

return unsubscribe;

}, buffer || buffers.none());
};

// 웹소켓 연결용 사가
const createConnectSocketSaga = (type, connectType, dataMaker) => {
const SUCCESS = `${type}_SUCCESS`;
const ERROR = `${type}_ERROR`;

return function\* (action = {}) {
const client = yield call(createSocket);
const clientChannel = yield call(
connectSocekt,
client,
connectType,
action,
buffers.expanding(500)
);

while (true) {
try {
const datas = yield flush(clientChannel); // 버퍼 데이터 가져오기
const state = yield select();

if (datas.length) {
const sortedObj = {};
datas.forEach((data) => {
if (sortedObj[data.code]) {
// 버퍼에 있는 데이터중 시간이 가장 최근인 데이터만 남김
sortedObj[data.code] =
sortedObj[data.code].timestamp > data.timestamp
? sortedObj[data.code]
: data;
} else {
sortedObj[data.code] = data; // 새로운 데이터면 그냥 넣음
}
});

const sortedData = Object.keys(sortedObj).map(
(data) => sortedObj[data]
);

yield put({ type: SUCCESS, payload: dataMaker(sortedData, state) });
}
yield delay(500); // 500ms 동안 대기
} catch (e) {
yield put({ type: ERROR, payload: e });
}
}

};
};



2. 특정 프로퍼티 값 추출

요소의 프로퍼티(id, content, completed)를 문자열 인수로 전달하면 todos의 각 요소 중, 해당 프로퍼티의 값만을 추출한 배열을 반환하는 함수를 작성하라.

단, for 문이나 Array#forEach는 사용하지 않도록 하자.

extractProperty.js
1
2
3
4
5
6
7
8
9
10
11
const todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function getValues(key) {}

console.log(getValues("id")); // [3, 2, 1]
console.log(getValues("content")); // [ 'HTML', 'CSS', 'Javascript' ]
console.log(getValues("completed")); // [ false, true, false ]

해답:

접기/펼치기 버튼
extractProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
const todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function getValues(key) {
return todos.map((todo) => todo[key]);
}

console.log(getValues("id")); // [3, 2, 1]
console.log(getValues("content")); // [ 'HTML', 'CSS', 'Javascript' ]
console.log(getValues("completed")); // [ false, true, false ]



3. 프로퍼티 정렬

요소의 프로퍼티(id, content, completed)를 문자열 인수로 전달하면 todos의 요소를 정렬하는 함수를 작성하라.

단, todos는 변경되지 않도록 하자.

참고: Array.prototype.sort

sortProperty.js
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
const todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function sortBy(key) {}

console.log(sortBy("id"));
/*
[
{ id: 1, content: 'Javascript', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 3, content: 'HTML', completed: false }
]
*/
console.log(sortBy("content"));
/*
[
{ id: 2, content: 'CSS', completed: true },
{ id: 3, content: 'HTML', completed: false },
{ id: 1, content: 'Javascript', completed: false }
]
*/
console.log(sortBy("completed"));
/*
[
{ id: 3, content: 'HTML', completed: false },
{ id: 1, content: 'Javascript', completed: false },
{ id: 2, content: 'CSS', completed: true }
]
*/

해답:

접기/펼치기 버튼
sortProperty.js
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
const todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function sortBy(key) {
return todos.sort((a, b) => (a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0));
}

console.log(sortBy("id"));
/*
[
{ id: 1, content: 'Javascript', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 3, content: 'HTML', completed: false }
]
*/
console.log(sortBy("content"));
/*
[
{ id: 2, content: 'CSS', completed: true },
{ id: 3, content: 'HTML', completed: false },
{ id: 1, content: 'Javascript', completed: false }
]
*/
console.log(sortBy("completed"));
/*
[
{ id: 3, content: 'HTML', completed: false },
{ id: 1, content: 'Javascript', completed: false },
{ id: 2, content: 'CSS', completed: true }
]
*/



4. 새로운 요소 추가

새로운 요소(예를 들어 { id: 4, content: ‘Test’, completed: false })를 인수로 전달하면 todos의 선두에 새로운 요소를 추가하는 함수를 작성하라. 단, Array#push는 사용하지 않도록 하자.

addNewProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function addTodo(newTodo) {}

addTodo({ id: 4, content: "Test", completed: false });

console.log(todos);
/*
[
{ id: 4, content: 'Test', completed: false },
{ id: 3, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 1, content: 'Javascript', completed: false }
]
*/

해답:

접기/펼치기 버튼
addNewProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function addTodo(newTodo) {
todos = [newTodo, ...todos];
}

addTodo({ id: 4, content: "Test", completed: false });

console.log(todos);
/*
[
{ id: 4, content: 'Test', completed: false },
{ id: 3, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 1, content: 'Javascript', completed: false }
]
*/



5. 특정 요소 삭제

todos에서 삭제할 요소의 id를 인수로 전달하면 해당 요소를 삭제하는 함수를 작성하라.

deleteProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function removeTodo(id) {}

removeTodo(2);

console.log(todos);
/*
[
{ id: 3, content: 'HTML', completed: false },
{ id: 1, content: 'Javascript', completed: false }
]
*/

해답:

접기/펼치기 버튼
deleteProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function removeTodo(id) {
todos = todos.filter((todo) => todo.id !== id);
}

removeTodo(2);

console.log(todos);
/*
[
{ id: 3, content: 'HTML', completed: false },
{ id: 1, content: 'Javascript', completed: false }
]
*/



6. 특정 요소의 프로퍼티 값 반전

todos에서 대상 요소의 id를 인수로 전달하면 해당 요소의 completed 프로퍼티 값을 반전하는 함수를 작성하라.

hint) 기존 객체의 특정 프로퍼티를 변경/추가하여 새로운 객체를 생성하려면 Object.assign 또는 스프레드 문법을 사용한다.

reverseProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function toggleCompletedById(id) {}

toggleCompletedById(2);

console.log(todos);
/*
[
{ id: 3, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: false },
{ id: 1, content: 'Javascript', completed: false }
]
*/

해답:

접기/펼치기 버튼
reverseProperty.js
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
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

// 스프레드 버전
function toggleCompletedById1(id) {
todos = todos.map((todo) =>
todo.id !== id
? todo
: todo.completed
? { ...todo, completed: false }
: { ...todo, completed: true }
);
}

// Object.assign 버전
function toggleCompletedById2(id) {
todos = todos.map((todo) =>
todo.id !== id
? todo
: todo.completed
? Object.assign({}, todo, { completed: false })
: Object.assign({}, todo, { completed: true })
);
}

toggleCompletedById1(2);

console.log(todos);
/*
[
{ id: 3, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: false },
{ id: 1, content: 'Javascript', completed: false }
]
*/

개선버전:

reverseProperty.js
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
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

// 스프레드 버전
function toggleCompletedById1(id) {
todos = todos.map((todo) =>
todo.id !== id ? todo : { ...todo, completed: !todo.completed }
);
}

//Object.assign 버전
function toggleCompletedById2(id) {
todos = todos.map((todo) =>
todo.id !== id
? todo
: Object.assign({}, todo, { completed: !todo.completed })
);
}

toggleCompletedById1(2);

console.log(todos);
/*
[
{ id: 3, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: false },
{ id: 1, content: 'Javascript', completed: false }
]
*/



7. 모든 요소의 completed 프로퍼티 값을 true로 설정

todos의 모든 요소의 completed 프로퍼티 값을 true로 설정하는 함수를 작성하라.

hint) 기존 객체의 특정 프로퍼티를 변경/추가하여 새로운 객체를 생성하려면 Object.assign 또는 스프레드 문법을 사용한다.

completeProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function toggleCompletedAll() {}

toggleCompletedAll();

console.log(todos);
/*
[
{ id: 3, content: 'HTML', completed: true },
{ id: 2, content: 'CSS', completed: true },
{ id: 1, content: 'Javascript', completed: true }
]
*/

해답:

접기/펼치기 버튼
completeProperty.js
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
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

// 스프레드 버전
function toggleCompletedAll1() {
todos = todos.map((todo) => ({ ...todo, completed: true }));
}

// Object.assign 버전
function toggleCompletedAll2(id) {
todos = todos.map((todo) => Object.assign({}, todo, { completed: true }));
}

toggleCompletedAll1();

console.log(todos);
/*
[
{ id: 3, content: 'HTML', completed: true },
{ id: 2, content: 'CSS', completed: true },
{ id: 1, content: 'Javascript', completed: true }
]
*/



8. completed 프로퍼티의 값이 true인 요소의 갯수 구하기

todos에서 완료(completed: true)한 할일의 갯수를 구하는 함수를 작성하라.

단, for 문, Array#forEach는 사용하지 않도록 하자.

countTrue.js
1
2
3
4
5
6
7
8
9
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function countCompletedTodos() {}

console.log(countCompletedTodos()); // 1

해답:

접기/펼치기 버튼
countTrue.js
1
2
3
4
5
6
7
8
9
10
11
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function countCompletedTodos() {
return todos.filter((todo) => todo.completed).length;
}

console.log(countCompletedTodos()); // 1

Array#reduce를 사용할 수도 있다.

countTrue.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function countCompletedTodos() {
return todos.reduce(
(acc, cur) => (cur.completed === true ? acc + 1 : acc),
0
);
}

console.log(countCompletedTodos()); // 1



9. id 프로퍼티의 값 중에서 최대값 구하기

todos의 id 프로퍼티의 값 중에서 최대값을 함수를 작성하라.

단, for 문, Array#forEach는 사용하지 않도록 하자.

getIdMax.js
1
2
3
4
5
6
7
8
9
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function getMaxId() {}

console.log(getMaxId()); // 3

해답:

접기/펼치기 버튼
getIdMax.js
1
2
3
4
5
6
7
8
9
10
11
let todos = [
{ id: 3, content: "HTML", completed: false },
{ id: 2, content: "CSS", completed: true },
{ id: 1, content: "Javascript", completed: false },
];

function getMaxId() {
return todos.length ? Math.max(...todos.map((todo) => todo.id)) : 0;
}

console.log(getMaxId()); // 3

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !