Array HOF 연습 문제

Seongkyun Yu·2020년 12월 7일
0

TIL - Javascript

목록 보기
26/28

기존 블로그에 작성한 내용을 velog로 이전한 글입니다


1. html 생성

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

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>
*/

해답:

접기/펼치기 버튼
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());
접기/펼치기 버튼
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는 사용하지 않도록 하자.

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 ]

해답:

접기/펼치기 버튼
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

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 }
]
*/

해답:

접기/펼치기 버튼
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는 사용하지 않도록 하자.

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 }
]
*/

해답:

접기/펼치기 버튼
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를 인수로 전달하면 해당 요소를 삭제하는 함수를 작성하라.

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 }
]
*/

해답:

접기/펼치기 버튼
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 또는 스프레드 문법을 사용한다.

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 }
]
*/

해답:

접기/펼치기 버튼
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 }
]
*/

개선버전:

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 또는 스프레드 문법을 사용한다.

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 }
]
*/

해답:

접기/펼치기 버튼
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는 사용하지 않도록 하자.

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

해답:

접기/펼치기 버튼
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를 사용할 수도 있다.

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는 사용하지 않도록 하자.

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

해답:

접기/펼치기 버튼
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

참고자료: poiemaweb.com

profile
FrontEnd Developer

0개의 댓글