[アルゴリズム]KACAブラインド2019-1オープンチャットルーム解答と私のコードコメント(JS)



解題と解答のコードを記録したいのですが、主なポイント、改善が必要なところ、さらに勉強しなければならないところだと思います.
この問題はタイトル通り2019年に行われたテストです.
次のリンクで問題を表示できます.
https://programmers.co.kr/learn/courses/30/lessons/42888

0.概要


私が問題に答えるとき、コードに気を配る部分は、読めるコードと定数を管理することです.
問題はチャットルームの記録に3種類の動作があり,対応する情報があることである.
だから私が使った言語javaのEnumのように管理してみました.
また、ES 6の文法をうまく利用したいと考えています.
だからOptional PropertyかString Interpolationが入っています

1.初解のコード

function solution(recordList) {
  const Operation = {
    Enter: { key: 'Enter', message: '들어왔습니다' },
    Leave: { key: 'Leave', message: '나갔습니다' },
    Change: { key: 'Change', message: '' },
  };

  const processedRecordList = recordList.map((record) => {
    const divided = record.split(' ');
    return {
      uid: divided[1],
      operation: divided[0],
      ...(divided[2] && { newNickname: divided[2] }),
    };
  });

  const uidNicknameMap = new Map();
  processedRecordList.forEach((record) => {
    if (Operation.Leave.key !== record.operation) {
      uidNicknameMap.set(record.uid, record.newNickname);
    }
  });

  const result = [];
  for (let record of processedRecordList) {
    const { uid, operation } = record;

    if (Operation.Change.key === operation) {
      continue;
    }

    result.push(
      `${uidNicknameMap.get(uid)}님이 ${Operation[operation].message}.`,
    );
  }
  return result;
}

2.私が思いついたポイント


最初の問題はこれほど難しいものはない.
kakaoの解説に示すように,関連配列(map)を用いることは容易に解決できる問題である.
私のコードにもう少しハイライトをつけたいです.
△同じような質問をしたが、採点した人はもう少し見てほしい.今考えるとちょっと恥ずかしい.
そこで、ES 6の上手な使い方、JSでのEnumの使い方などをさらに増やしていきたいと思います.

3.改善すべき点


変数をまとめてコメントする


まず、変数は関数の真ん中で宣言されることに注意してください.
どの変数が顕微鏡内で使われているか分かりにくい.
そこで、私は以下のように変更しました.
function solution(recordList) {
  // Operation const object 선언
  const Operation = {
    Enter: { name: 'Enter', message: '들어왔습니다' },
    Leave: { name: 'Leave', message: '나갔습니다' },
    Change: { name: 'Change', message: null },
  };

  const uidNicknameMap = new Map(); // uid - nickname을 연관지을 객체
  const result = []; // 채팅 결과를 담을 객체
  
  ...
  // 구현 부분 생략

  return result;
}
注釈で簡単に説明し、変数の用途を示した.

不要な論理を減らし、コードを最適化

recordList
    // record를 의미가 담긴 객체 형태로 변환한다
    .map((record) => {
      const [operation, uid, nickname] = record.split(' ');

      // 닉네임이 있다면 uid - nickname 맵에 넣어준다
      if (nickname) {
        uidNicknameMap.set(uid, nickname);
      }

      return {
        operation: Operation[operation],
        uid,
        ...(nickname && { nickname }),
      };
    })
まず、チャットレコードをdistributeという変数に分割します.
ES 6のArray Destructre構文を用いて色を塗った.
newNicknameという変数名も変更されました.
初めて入場した時はnewNicknameよりもあだ名の方が意味的に合っていたようです.
初めてEnterをやった人かもしれないから!
2回目はforeachを何度も使いますが、一度もなくてもいいです.
mapでオブジェクトを変換する過程でuid-ニックネーム関連付けが同時に実行されます.
第三に、オペレーション属性は、オペレーション文字列と同様に返されるオブジェクトに含まれます.
コードを裁断するときに、私がオブジェクト化した定数を加えました.
今はnewRecordoperation.メッセージを介してメッセージに直接アクセスできます.
あと、もっと説明するなら
        ...(nickname && { nickname }),
この構文は、ニックネームを変更するアクションに別名変数はありません.(undefined)
ニックネーム属性を追加する必要はありません.ニックネームが存在する場合にのみニックネーム属性を追加できます.
4つ目は上のmap()と最後に結果を導いたforeach()を接続して記入します.
    .forEach(({ uid, operation }) => {
      if (operation === Operation.Change) return;
      result.push(`${uidNicknameMap.get(uid)}님이 ${operation.message}.`);
    });
Object Destructingでuid、operationがすぐに利用できます.
を選択します.Changeは彼に反撃させ、彼を続けさせた.
次に、beckを使用して文字列の構文をマージします.

最終変更コード

function solution(recordList) {
  // Operation const object 선언
  const Operation = {
    Enter: { name: 'Enter', message: '들어왔습니다' },
    Leave: { name: 'Leave', message: '나갔습니다' },
    Change: { name: 'Change', message: null },
  };

  const uidNicknameMap = new Map(); // uid - nickname을 연관지을 객체
  const result = []; // 채팅 결과를 담을 객체

  recordList
    // record를 의미가 담긴 객체 형태로 변환한다
    .map((record) => {
      const [operation, uid, nickname] = record.split(' ');

      // 닉네임이 있다면 uid - nickname 맵에 넣어준다
      if (nickname) {
        uidNicknameMap.set(uid, nickname);
      }

      return {
        operation: Operation[operation],
        uid,
        ...(nickname && { nickname }),
      };
    })
    .forEach(({ uid, operation }) => {
      if (operation === Operation.Change) return;
      result.push(`${uidNicknameMap.get(uid)}님이 ${operation.message}.`);
    });

  return result;
}
最後に変更したコードは上記の通りです.変数もよく上に表示され、用途も説明されています.
また,forEach,forを混用したコードも排除した.一度に時間の無駄を減らす.
もっと読みやすくなった気がします!(私から見れば!)
さらに説明する必要がある場合は、ご自由にフィードバックしてください.