두 개의 주어진 배열이 있을 때, 두번째 인자로 전달된 배열이 첫번째 인자의 배열의 부분집합인지를 boolean을 이용하여 판단하시오.

입출력 예시

f([1,2,3,4,5],[1,3]) //true
f([1,2,3,4,5],[6,7]) //false
f([10,99,123,7],[11,100,99,123]) //false

내가 작성한 코드(시간 복잡도 개선, advanced 모두 통과한 코드)

const isSubsetOf = function (base, sample) {
  // TODO: 여기에 코드를 작성합니다.

  //문제 이해
  //base가 전체집합이고, sample이 부분집합이다. 
  //따라서 sample은 반드시 base의 원소들을 이용하여 만들어져야 한다.

  //바로 처리를 할 수 있는 경우는 뭐가 있을까?
  /*
  -sample이 []인 경우: true;
  -sample이 base보다 길이가 긴 경우: false;
  */

  //예시 이해
  //입출력 1: [1,3]의 각 요소는 base에 포함이 되어 있다. 
  //입출력2: [6,7]의 각 요소는 base에 미포함되어 있다.
  //입출력 3: 99,123은 base에 있지만, 11과 100은 미포함되어 있다. 

  //내가 생각하는 해결책
  /*
  base를 순회하면서, 객체를 만든다. 
  예를 들어 입출력 예시 1의 경우 {1:1,2:1,3:1,4:1,5:1} 이렇게.
  sample을 순회하면서, sample의 요소가 객체의 키 값으로써 존재하지 않는다면 ,
  반복문을 종료하고 false를 리턴한다.
  만약에 반복문을 false 리턴 없이 다 돌았다면, 
  그것은 base의 부분집합이라는 뜻이 되니까 true를 리턴한다. 
  */
  //엣지 케이스 처리
  if(sample.length === 0) return true;
  if(sample.length > base.length) return false;

  //엣지 케이스 이외의 경우 처리!

  //객체 만들기
  let baseObj = {};
  for(let i = 0; i < base.length; i++){
    if(baseObj[base[i]] === undefined){
      baseObj[base[i]] = 1;
    }
  }

  //sample 순회하기
  for(let j = 0; j < sample.length; j++){
    if(baseObj[sample[j]] === undefined) return false;
		//!(sample[j] in baseObj)라고 작성 해도 된다. 
  }
  return true;
};

------------------------
아래와 같이 쓰면 시간복잡도가 N*N이다. 배열을 두번 순회하기 때문이다. 
return sample.every((item) => base.includes(item)); 

그러면 위의 경우도 배열과 객체에 대해 한번씩 순회하는 거니까, N*N이 아니냐고 생각할 수 있는데
객체에서 키 값을 조회하는 경우, 객체는 해시구조이기 때문에 시간복잡도가 O(1)로 일정하다고 한다.
그래서 모든 테스트가 통과된다고 한다. [스택오버플로우 답변](<https://stackoverflow.com/questions/45266944/complexity-of-accessing-data-in-an-object>) 참조.
Javascript objects are actually Hashes, 
so the complexity is O(1) for all engines.
obj.field is an alias for obj['field'], so they have the same performances.