# Daily Codewars #20

# Question

codewars link (opens new window) Implement the function unique_in_order which takes as argument a sequence and returns a list of items without any elements with the same value next to each other and preserving the original order of elements.

For example:

uniqueInOrder('AAAABBBCCDAABBB') == ['A', 'B', 'C', 'D', 'A', 'B']
uniqueInOrder('ABBCcAD')         == ['A', 'B', 'C', 'c', 'A', 'D']
uniqueInOrder([1,2,2,3,3])       == [1,2,3]

# My Solution

//version1
var uniqueInOrder=function(iterable){
    if(iterable.length==0) return [];
    var arr=[iterable[0]];
    if(typeof iterable === 'string') iterable=iterable.split('');
    iterable.reduce(function(prev,cur) {
        if(prev!=cur) arr.push(cur);
        return cur;
    });
    return arr;
}
//version2
var uniqueInOrder=function(iterable){
  if(Array.isArray(iterable)) iterable=iterable.join('');
  return iterable.length==0? [] : iterable.match(/(.)(?!\1+)/g).map(function(item) {
    return isNaN(parseInt(item))? item : parseInt(item);
  });
}

1번은 벼르던 reduce를 사용해보았다. prev랑 cur이 다르면 그게 값이 바뀌는 시점으로 인식해 배열에 집어넣는다는. 그런데 제일 앞이나 제일 뒤 문자 중 하나는 포기해야해서 처음에 값을 집어넣고 해야한다는 더러움이 있다. 2번을 그냥 정규표현식으로만 반환하면 number로 이루어진 배열도 string으로 쪼개져서 반환된다는 버그가 있어 map으로 해주었다.

# @ooflorent's Solution

function uniqueInOrder(it) {
  var result = []
  var last
  
  for (var i = 0; i < it.length; i++) {
    if (it[i] !== last) {
      result.push(last = it[i])
    }
  }
  return result
}

아아. js는 string이랑 array모두 [i]로 접근할 수 있지... 길이만큼 돌면서 문자가 last랑 다르면 문자를 last에 넣고 result배열에 넣어준다. 현재 돌고있는 문자를 last라고 본거구나. 똑똑이. 깔끔하다. 근데 for문하고 Array.map같은 건 복잡도 차이가 날까? 궁금.

# @Freywar's Solution

var uniqueInOrder = function (iterable)
{
  return [].filter.call(iterable, (function (a, i) { return iterable[i - 1] !== a }));
}

빈 배열에 iterable을 문맥으로 한 call을 걸어주고 filter로 바로 전 문자와 다른 것들만 뽑아낸다. 스킬풀하다.