コプリット[鬼#14]



プレゼントボックス情報を含む配列と文字列を入力して、条件を満たすプレゼントがあるかどうかを返します。


I/O例:
const giftBox = ['macbook', 'mugcup', ['eyephone', 'postcard'], 'money'];

let output = unpackGiftbox(giftBox, 'iphone');
console.log(output); // --> false

output = unpackGiftbox(giftBox, 'postcard');
console.log(output); // --> true
マイコード:
function unpackGiftbox(giftBox, wish) {
  // 1. giftBox와 wish를 unpackGiftbox의 인자로 받는다.
  // 2. for문을 써서 giftBox의 요소들을 훑는다.
  // 3. 만약 giftBox[i] === wish 라면 true를 반환한다.
  //   3-1. giftBox[i]이 배열이라면 unpackGiftbox(giftBox[i], wish)를 실행한다.
  //   3-2. 1 ~ 3 과정을 반복하고 giftBox[i] !== wish 라면 false를 반환한다.
  
  for (let i = 0; i < giftBox.length; i++){
    if (wish === giftBox[i]) return true;
    if (Array.isArray(giftBox[i])){
      const result = unpackGiftbox(giftBox[i], wish);
      if (result === true) return true;
    } 
  }
  return false; // base case
}

難しい理由は?


配列に配列がある場合は、unpackGiftbox関数を再読み込みして再帰を実行できます.
return unpackGiftbox(giftBox[i], wish)
最初はなぜこのまま車に戻れないのか理解できなかったのでgithubに質問しました.
const result = unpackGiftbox(giftBox[i], wish);
if (result === true) return true;
このように変数を宣言し、関数に戻り値を割り当てる理由が分かりました.戻り値がtrueでない場合、終了するのではなく、次の部分をチェックし続けるためです.今回見たHAの7番目の問題はこの問題とあまり差がないようです.この問題をあまり見なかったら、HA 7の問題ができなかったかもしれません.

2. Reference

function unpackGiftbox(giftBox, wish) {
   // recursive case
   let anotherBoxes = [];
   for (let i = 0; i < giftBox.length; i++) {
     if (giftBox[i] === wish) {
       return true;
     } else if (Array.isArray(giftBox[i])) {
       anotherBoxes = anotherBoxes.concat(giftBox[i]);
     }
   }

   if (anotherBoxes.length > 0) {
     return unpackGiftbox(anotherBoxes, wish);
   }

   // base case
   return false;
 }

3. Feedback


配列に配列がある場合は、新しい配列に配置し、unpackGiftboxに配置して再帰を実行します.私のコード変数を割り当て、その変数がtrueである場合、trueを返す面倒があります.このコードにはそんな面倒はありません.