2011-01-12 4 views
8

다음은 JavaScript 전문가를위한 구현 세부 질문입니다.JavaScript로 복잡한 의사 결정 테이블 구현

필자는 입력 값 7 비트의 값에 따라 필드 값이 복잡한 방식으로 나타나는 여러 필드가있는 UI가 있습니다. 사용자가 더 많은 응용 프로그램을 보면서 정기적으로 변경되는 가능한 128 개의 값 중 하나에 대해 정확히 표시되어야하는 것은 무엇입니까?

지금 당장은 if-then-else 빗을 통해 의사 결정 트리로 구현되었지만 요구 사항이 변경되고 일종의 권리를 얻기가 쉽지 않습니다.

내가 생각했습니다

하나의 구현 방식에서 0x7f이 0x0의 값의 배열을 만든 다음 각각의 위치에서 폐쇄를 저장하는 것입니다 -

var tbl; // initialize it with the values 
    ... 
tbl[0x42] = function(){ doAThing(); doAnotherThing(); } 

다음으로 호출

tbl[bitsIn](); 

적어도 결정 로직을 많은 양의 할당으로 만듭니다.

질문 : 더 좋은 방법이 있습니까?

(업데이트 : 거룩한 쓰레기는 어떻게 '아약스 아이폰 태그'에 대한 그 라인이 얻을 의심 할 여지가 조금 수수께끼 없었다.)

업데이트

무슨 일이 있었 그래서 ? 기본적으로 나는 네 번째 옵션을 택했다. 논리가 충분히 복잡하여 결국 서버에 진리 테이블을 생성하는 파이썬 프로그램을 만들었습니다. (실제로는 Groovy 코드를 생성합니다. 호스트는 Grails 응용 프로그램입니다.) 결정 논리를 서버로 완전히 옮깁니다. 이제 JavaScript 측은 다양한 필드의 값을 포함하는 JSON 객체를 해석합니다.

결국 이것은 하나 이상의 반복을 거쳐 비트 벡터에 의해 인덱싱 된 데이터베이스 테이블의 데이터가됩니다.

테이블 구동 부분이 확실히 나왔습니다. 거기에 이미 반 12되었습니다 새로운 디스플레이에 대한 특정 요구 사항이 변경되었습니다.

+2

, 당신의 리팩토링 생각이 소리입니다,하지만 TBH 전 귀하의 설명에서 확실하지 않은 것이 무엇입니까? P –

+0

각 비트가 특정 동작을 결정합니까? 그렇다면 왜 [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40]에 대한 값에 대해 비트 AND를 수행하지 마십시오. – draeton

+0

@Martin, 요점은 내 테이블보다 더 유연하고 유연한 방법이 있는지입니다. 람다들. –

답변

1

의사 결정 트리를 직접 작성하는 대신 서버에서 생성하는 것이 고려 되었습니까? 어떤 표현이라도 깨끗하고, 사용하기 쉽고, 수정 한 다음 클라이언트 쪽에서는 못생긴 아직 효율적인 자바 스크립트로 컴파일하십시오.

의사 결정 트리는 데이터로 표현하기가 쉽고 전통적인 트리 데이터 구조로 이해하고 작업하기 쉽습니다. 당신은 어떤 형태로든 당신에게 의미있는 나무를 저장할 수 있습니다. 데이터를 유효성 확인하고 수정하는 것도 또한 간단합니다.

그렇다면 의사 결정 트리를 사용해야 할 때 JavaScript를 컴파일 할/직렬화하여 큰 if-else-switch 또는 해시 혼란을 일으킬 수 있습니다. 이것은 또한 상당히 똑바로 앞으로 몇 백 개의 요소가있는 switch을 유지하는 것보다 훨씬 쉬워야합니다.

2

상황 (설명했듯이)이 너무 불규칙하기 때문에 더 좋은 방법이없는 것처럼 보입니다. 그래도 점프 테이블을 개선 할 것을 제안 할 수 있습니다. 오류 및 중복이 있다고 언급하셨습니다. 따라서 클로저에 명시 적으로 할당하는 대신 명시 적 종료를 복제 할 필요가 없도록이를 명명 된 함수에 할당 할 수 있습니다.

var doAThingAndAnother = function(){ doAThing(); doAnotherThing(); } 

var tbl; // initialize it with the values 
    ... 
tbl[0x42] = doAThingAndAnother; 
tbl[0x43] = doAThingAndAnother; 

그다지 개선되지는 않았지만, 내가 생각할 수있는 유일한 것입니다! 당신은 다른 문제의 대부분을 다룬 것으로 보입니다. 요구 사항이 많이 바뀌는 것처럼 보이기 때문에 우아함을 잊어 버리고 우아한 디자인은 아니지만 여전히 변경하기 쉽습니다.

5

두 가지 옵션이 있습니다.두 솔루션 모두에 공통

다음과 같은 명명 된 기능은 다음과 같습니다

function aThing() {} 
function anotherThing() {} 
function aThirdThing() {} 

스위치 방식

function exec(bits) { 
switch(bits) { 
    case 0x00: aThing(); anotherThing(); break; 
    case 0x01: aThing(); anotherThing(); aThirdThing(); break; 
    case 0x02: aThing(); aThirdThing(); break; 
    case 0x03: anotherThing(); aThirdThing(); break; 
    ... 
    case 0x42: aThirdThing(); break; 
    ... 
    case 0x7f: ... break; 
    default: throw 'There is only 128 options :P'; 
    } 
} 

당신이

를 호출 할 것 두 경우 모두지도 방법

function exec(bits) { 
    var actions = map[bits]; 
    for(var i=0, action; action=actions[i]; i++) 
     action(); 
} 

var map = { 
0x00: [aThing, anotherThing], 
0x01: [aThing, anotherThing, aThirdThing], 
0x02: [aThing, aThirdThing], 
0x03: [anotherThing, aThirdThing], 
    ... 
0x42: [aThirdThing], 
    ... 
}; 

exec(0x42); 
+0

그 루프는'for (행동의 var 행동) action();'이 될 수 없었습니다. –

+0

그럴 수는 있지만별로 의미가 없습니다. 이 경우의 액션은 함수 참조의 배열입니다. 배열에 대해 (var i in array) 배열을 반복하지 않으려면 속도가 훨씬 느리고 브라우저에서 결과가 고르지 않을 수 있습니다. 일부 브라우저는 배열의 "length"속성을 객체의 다른 멤버로 취급하고 함수 참조와 함께 제공합니다. –

+0

[] .propertyIsEnumerable ('length') === false – draeton

1

난 당신이 좀 걸릴하려는 경우 자바 스크립트 의사 결정 트리 도구의 거친 예를 가지고 : 나는 당신의 문제를 이해하는 것과

http://jsfiddle.net/danw/h8CFe/

관련 문제