2014-07-11 8 views
0

자바 스크립트에서 간단한 필터링 언어를 만들고 싶습니다. 검색 언어를 만드는 방법은 무엇입니까?

내가, 제품의 집합 내에서 검색 할

말 :

텍스트의 하나의 입력으로
product=[ 
    {price:10,name:"T-Shirt",category:"Clothing",published_at:"07-08-2014",size:"10x30",color:"#0000FF"}, 
    {price:20,name:"Chair",category:"Furniture",published_at:"09-03-2013",size:"30x30",color:"#00FF00"}, 
    {price:30,name:"iPhone",category:"Phones",published_at:"17-03-2014",size:"40x30",color:"#FF00FF"}, 
    {price:40,name:"Samsung Galaxy",category:"Phones",published_at:"12-01-2012",size:"10x60",color:"#00BBBB"}, 
]; 

, 내가 예를 들어,이 배열 내에서 조회 할 수 있도록하고 싶습니다 :

  • cat:Clothing는 =>는 t- 셔츠를 다시 제공
  • price:>15 => 의자, 아이폰, 삼성 갤럭시를 다시 제공
  • name:iP => 필터 이름을 여물과
  • price:>15&&size:>35x25 => 필터 이름 물마루 아이폰을 돌려주고, 나는 그들이

    를 다시 제공 coffeescript에서 사용)

하지만 선택할 수있는) 그리고 그것을 사용하는 것이 좋은 생각이라면? 어떤 아이디어?

+0

서버에 DB가 있고 아약스를 통해 질문하는 것이 더 유용하지 않습니까? – MightyPork

+0

AngularJS 필터를 살펴보십시오. 잔인한 사람 일지 모르지만, 아직도 보니 반갑습니다. –

+0

질문은 언어를 만드는 방법에 대한 것이고, 마지막에는 DB 언어로 번역되거나 네이티브 자바 스크립트로 번역 될 수 있습니다. Angular JS 필터는 내가 발명 한 언어를 구문 분석하지 않습니다 (마법이 아닙니다) @NikhilBaliga – edi9999

답변

0

난 (BISON 유사) JISON으로 테스트하는 결정

/* description: Parses end executes mathematical expressions. */ 

/* lexical grammar */ 
%lex 
%% 

\s+     /* skip whitespace */ 
[0-9]+("."[0-9]+)?\b return 'NUMBER' 
">"      return '>' 
"price:"    return 'PRICE' 
<<EOF>>    return 'EOF' 
"name:"    return 'NAME' 
[a-z]+    return 'STRING' 
","     return 'COMMA' 


/lex 

/* operator associations and precedence */ 

%left 'COMMA' 
%left 'PRICE' 'NAME' 


%start expressions 

%% /* language grammar */ 

expressions 
    : e EOF 
     { typeof console !== 'undefined' ? console.log($1) : print($1); 
      return $1; } 
    ; 

e 
    : 'PRICE' '>' e 
     {$$ = {price:{gt:$3}};} 
    | 'NAME' e 
     {$$ = {name:{contains:$2}};} 
    | NUMBER 
     {$$ = Number(yytext);} 
    | STRING 
     {$$ = String(yytext);} 
    | e 'COMMA' e 
     { for (var attrname in $1) { $3[attrname]=$1[attrname]; $$ = $3; }} 
    ; 

파서의 결과가 다음

price:>30=>{ price: { gt: 30 } }

name:blabla,price:>10=>{ price: { gt: 10 }, name: { contains: 'blabla' } }

그것은 직접 구문 분석과 거래를하지 않기 때문에

name:test=>{ name: { contains: 'test' } }

이 솔루션은, 나에게 조금 더 휴대용 보인다.

1

저는 이것이 라이브러리 없이도 할 수있을 정도로 간단하다고 생각합니다.

가 여기에 내 균열의 : 요청에 따라

http://jsfiddle.net/qrz48/2/

// polyfill Array.prototype.forEach if you need to support older browsers... 
// there's one at: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach 

var product = [ 
    {price:10,name:"T-Shirt",category:"Clothing",published_at:"07-08-2014",size:"10x30",color:"#0000FF"}, 
    {price:20,name:"Chair",category:"Furniture",published_at:"09-03-2013",size:"30x30",color:"#00FF00"}, 
    {price:30,name:"iPhone",category:"Phones",published_at:"17-03-2014",size:"40x30",color:"#FF00FF"}, 
    {price:40,name:"Samsung Galaxy",category:"Phones",published_at:"12-01-2012",size:"10x60",color:"#00BBBB"} 
]; 

// extend this as you require new search operators. 
var operators = { 
    "==": function(a, b) {return a == b;}, 
    "===": function(a, b) {return a === b;}, 
    ">": function(a, b) {return a > b;}, 
    ">=": function(a, b) {return a >= b;}, 
    "<": function(a, b) {return a < b;}, 
    "<=": function(a, b) {return a <= b;}, 
    "*": function(a, b) {return a.indexOf(b) > -1;} 
}; 

// usage: find("category", "===", "Clothing") 
function find(key, operator, condition, searchIn) { 
    if(! searchIn) { 
     searchIn = product; 
    } 
    var result = []; 
    searchIn.forEach(function(item) { 
     if(operators[operator](item[key], condition)) { 
      result.push(item); 
     } 
    }); 
    return result; 
} 

// usage: query("category:===:Clothing"); 
function query(str) { 
    var conditions = str.split("&&"); 
    var result = []; 
    conditions.forEach(function(condition, index) { 
     var parts = condition.split(":"); 
     var key = parts[0]; 
     var operator = parts[1]; 
     var condition = parts[2]; 
     var searchIn = (conditions.length > 1 && index > 0) ? result : null; 
     result = find(key, operator, condition, searchIn); 
    }); 
    return result; 
} 


// usage 
console.log(query("category:===:Clothing")); 
console.log(query("price:>:20")); 
console.log(query("name:*:iP")); 
console.log(query("price:>:20&&name:*:Galaxy")); 

당신은 콜론이 필요하다는 것을 제외하고, 위의 query 함수에 검색 문자열을 전달할 수 있습니다 전과 조건 연산자 다음에. 예를 들어, 가격이 20보다 큰 모든 제품을 찾아 실행합니다

query("price:>:20&&category:===:Clothing"); 

내가 어떻게 생각하지 수 : 또한 문제의 형식을 사용하여 검색 조건을 결합 할 수 있습니다

query("price:>:20"); 

size 비교를 수행하려면 크기 데이터를 별도의 값으로 분리하지 않아도됩니다. 쉬울 것 sizeXsizeY이 작성 그냥 아주 재미 오히려

query("sizeX:>:30&&sizeY:>:20"); 

같은 것을 사용하여 비교. 어떻게 생각해?

+0

그것은 그러한 언어를 작성하기 쉽습니다. 나는 그동안 JISON에 언어 파서를 썼다. 어떤 솔루션을 생각해 볼 필요가 있습니다. – edi9999

+0

나는 당신을 위해 유지하기가 더 쉽고, 미래의 개발자들이 프로젝트에서 작업하는 것이 가장 쉽고, 다른 라이브러리들과의 의존도가 가장 적습니다. –