2016-12-28 7 views
0

그래, 배열의 websocket 클라이언트 연결이 있습니다. 이 배열에 여러 다른 시스템에 대한 연결이 포함되어 있다고 가정 해보십시오. 각기 다른 문자 (1,2,3 등)가 다른 호스트를 대표한다고 상상해보십시오. 그것은 다음과 같습니다 클라이언트가 응답하지 않는 경우배열 반복을 최소화하기 위해 배열을 목표로 정렬

const conns = [1,2,3,1,2,3,1,2,3, ... etc]; 

근거, 내가하지 않으려한다 : 내가하고 싶은 것이

const conns = [1,1,1,3,3,1,3,2,2,2,2,3,2,1,1,2,2]; 

는, 일종의 배열과 같이이다 동일한 호스트에 다시 시도하십시오. 다른 호스트의 클라이언트에게 메시지를 보내고 나중에 원래 호스트로만 돌아가 봅니다. 이것은 기본적으로 라운드 로빈 유형과 같습니다.

  1. 이 고유의 목록을 통해 배열
  2. 반복 처리의 모든 다른 호스트 (고유 문자를) 찾을하고있는 항목을 접합하기 :이처럼

    나는 배열을 정렬 할 수있는 가장 좋은 방법을 생각 원래대로 배열. ,

    [ 1, 2, 3, 4, 5, 11, 1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 3, 4, 1, 3, 4, 1, 3, 1, 3, 1, 1, 1 ] 
    

    이 코드의 자랑 아니에요 : 우리가 얻을, 위의 입력 주어진

    const list = [1,2,3,4,5,1,1,1,1,1,2,3,4,5,1,2,11,3,3,3,3,3,4,4,4,1,1,1]; 
    
    const _ = require('lodash'); 
    
    function findAndRemoveFirstMatch(m, list){ 
        for(var i = 0; i < list.length; i++){ 
         if(m === list[i]){ 
          return list.splice(i,1)[0]; 
         } 
        } 
    } 
    
    function getSorted(list){ 
    
        const ret = []; 
    
        const set = _.uniqBy(list, function(x){ 
         return x; 
        }); 
    
        while(list.length > 0){ 
    
         var i = 0; 
         while(i < set.length && list.length > 0){ 
          var item; 
          if(item = findAndRemoveFirstMatch(set[i],list)){ 
           ret.push(item); 
          } 
          i++; 
         } 
    
        } 
    
        return ret; 
    
    } 
    
    console.log(getSorted(list)); 
    

    // :

다음은 위의 알고리즘 내가 가지고있는 JS 코드 더 좋은 방법이 있는지 궁금해하고 있습니다. 위의 내용은이 입력에 적용되지만이를 정리하고 더 일반적인 방법을 찾고 있습니다.

더 빠르고 더 빠른 방법이 있습니까?

+1

그냥 ['Set' 객체 (https://developer.mozilla.org/en-를 만들 US/docs/Web/JavaScript/Reference/Global_Objects/Set) 생성자에 초기 배열을 전달합니다. 그러면 모든 고유 항목에 대한 반복 가능한 목록이 제공됩니다. – jfriend00

+0

@ jfriend00 yes 그렇긴하지만 프리미티브 대신 객체를 사용할 수 있습니까? 실제로는 문자열이 아닌 객체를 사용하고 있습니다. 개체를 원시 ID로 매핑 한 다음이를 생성자에게 전달한다고 가정합니다. 좋은 아이디어를 주셔서 감사합니다 –

+0

예, '설정'은 객체와 작동합니다. 문자열을 키로 사용할 필요가 없기 때문에 이것이 진정한 이점입니다. – jfriend00

답변

1

당신은 다르게 작업을 수행 할 수 있습니다

  • 종류의 입력을 - 나중에

  • 가 동일한 요소의 최대 수를 찾는 데 도움이됩니다 (요소, 귀하의 예제에서 10 = 1), CNT

  • 그들을 요소를 배포 할 수 CNT 버킷을 만들
  • 는 라운드 로빈 원칙을 다음 버킷에 의해 정렬 된 순서로 하나의 시작 부분에서보다

  • 병합 버킷

당신은 결국 더 이상 시리즈를 얻을이 방법은, 1 요소를 넣어. 하나 개의 요소 이상 N/2 번 나타날 때

[1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 3, 4, 1, 3, 4, 1, 3, 5, 1, 3, 5, 1, 3, 11, 1, 3, 1, 3] 

나쁜 경우가 있지만, 그 피할 수 있습니다.당신은 처음부터 키의 전체 목록을 주장하는 경우

var list = [1,2,3,4,5,1,1,1,1,1,2,3,4,5,1,2,11,3,3,3,3,3,4,4,4,1,1,1]; 
var a = list.sort(function(a, b) { return a - b; }); 
var cnt = a.reduce(function(res, cur) { 
    if (cur == res[0]) 
    return [cur, res[1]+1, Math.max(res[1]+1, res[2])] 
    else 
    return [cur, 1, Math.max(1, res[2])]; 
}, [null, 0, 0])[2]; 

var buckets = []; 
for (var i = 0; i < cnt; i++) 
    buckets[i] = []; 

var j = 0; 
for (var i = 0; i < a.length; i++) { 
    buckets[j].push(a[i]); 
    j = (j+1)%cnt; 
} 

var res = buckets.reduce(function(r, cur) { 
    return r.concat(cur); 
}); 

, 그것은 수도 있습니다

var list = [1,2,3,4,5,1,1,1,1,1,2,3,4,5,1,2,11,3,3,3,3,3,4,4,4,1,1,1]; 
var a = list.sort(function(a, b) { return a - b; }); 
var cnt = a.reduce(function(res, cur) { 
    if (cur == res[0]) 
     return [cur, res[1]+1, Math.max(res[1]+1, res[2])] 
    else 
     return [cur, 1, Math.max(1, res[2])]; 
}, [null, 0, 0])[2]; 

var buckets = []; 
for (var i = 0; i < cnt; i++) 
    buckets[i] = []; 

var j = 0; 
var cur = null; 
for (var i = 0; i < a.length; i++) { 
    if (cur != a[i]) 
     j = 0; 
    buckets[j].push(a[i]); 
    j = j+1; 
} 

var res = buckets.reduce(function(r, cur) { 
    return r.concat(cur); 
}); 
+0

나는 혼란 스럽다. 이상적으로 그것은 [1,2,3,4,11,1,2,3,4 ...] 등이어야한다? –

+0

@Alexander Mills의 업데이트 된 답변 –