Excel表格类型标准过滤器不完善的javascript实现

时间:2015-05-13 21:31:30

标签: javascript handsontable

所以我有一个与你在excel标准过滤器中找到的相同的ui。 (截图是与代码示例无关的任意示例)

enter image description here

我试图弄清楚如何评估条件的集合。 我的代码根据单元格检查条件,并且我添加了一个布尔属性来显示条件的结果

var filteredData = [];
for (var i = 0; i < data.length; i++) {
var row = data[i];
var rowObj = constructRowObject(
 pm, row);
 var condResArr = [];
 for (var r = 0; r < uiSelectionResultsArr.length; r++) {
   var cond = uiSelectionResultsArr[r],
   cellValue = rowObj[cond.colName],
   expType = cond.expression,
   value = cond.value;
   if(expType === "equal"){
     cond.evaluated  = (cellValue == value);
   }else if(expType === "not-equal"){
     cond.evaluated  = (cellValue != value);

   }else if(expType === "greater"){
     cond.evaluated  = (cellValue > value);

   }else if(expType === "less"){
     cond.evaluated  = (cellValue < value);
   }   
 }
 //now we have a list of booleans added to our cond objects
 //undefined group is the first one (A and D) bracketed by
 //adjacent row pairs - therefore sort by id
 var sorted =  _.sortBy(uiSelectionResultsArr, 'id'); 
}

因此,作为我最终得到的一个例子是

  [{
        "colName": "id",
        "id": 1,
        "expression": "greater",
        "value": "50",
        "evaluated": false
    }, {
        "colName": "id",
        "id": 2,
        "expression": "less",
        "value": "100",
        "operation": "and",
        "evaluated": true
    }, {
        "operation": "or",
        "id": 3,
        "colName": "id",
        "expression": "equal",
        "value": "200",
        "evaluated": false
    }]

现在我需要通过它们的逻辑运算符加入评估的布尔值,即:它们所在的组 - 由相邻的标准行隐含。在这种情况下,它将是

  

if(false&amp;&amp; true)||假

这显然是假的,但我想做的是构建这个/无论条件表达式在运行时是什么......是否可以在javascript中做这样的事情。

我不是要求批评ui甚至逻辑,我只是​​好奇你是否可以&#34;在运行时使用逻辑运算符评估一组布尔值&#34;

到目前为止,我最好的猜测是这样的,但它有明显的问题。

$("#filter-btn").click( function(e) {
  e.preventDefault();
  console.log("uiSelectionResultsArr: "+ JSON.stringify(uiSelectionResultsArr));
  //order of columns could have been moved can't just use index
  var constructRowObject = function(pm, handsonDsRow) {
    var colHeaders = pm.currentHeaders;
    var newRowObj = {};
    for (var index = 0; index < colHeaders.length; index++) {
      newRowObj[colHeaders[index]] = handsonDsRow[index];
    }
    //console.log("constructRowObject: "+ JSON.stringify(newRowObj));
    return newRowObj;
  };

  /*
  * [{"operation":"and","id":1,"colName":"id","expression":"equal","value":"500"},
  * {"operation":"or","id":2,"colName":"col5","expression":"smaller","value":"100"}]
  */
  // the filter in run per table row
  // using the condions in
  // uiSelectionResultsArr we decide
  // if each row should be in the
  // results
  var data = hot.getData();
  var filteredData = [];
  for (var i = 0; i < data.length; i++) {
    var row = data[i];
    var rowObj = constructRowObject(pm, row);
    for (var r = 0; r < uiSelectionResultsArr.length; r++) {
      var cond = uiSelectionResultsArr[r],
      cellValue = rowObj[cond.colName],
      expType = cond.expression,
      value = cond.value;
      if(expType === "equal"){
        cond.evaluated  = (cellValue == value);
      }else if(expType === "not-equal"){
        cond.evaluated  = (cellValue != value);

      }else if(expType === "greater"){
        cond.evaluated  = (cellValue > value);

      }else if(expType === "smaller"){
        cond.evaluated  = (cellValue < value);
      }

    }
    console.log("uiSelectionResultsArr (after evaluated): "+JSON.stringify(uiSelectionResultsArr));
    //now we have a list of booleans added to our cond objects
    //undefined group is the first one (A and D) bracketed by
    //adjacent row pairs - therefore sort by id
    var sorted =  _.sortBy(uiSelectionResultsArr, 'id');
    //console.log("sorted: "+JSON.stringify(sorted));
    /*sorted: [{"colName":"id","id":1,"expression":"greater","value":"50","evaluated":false},
    {"colName":"id","id":2,"expression":"smaller","value":"100","operation":"and","evaluated":true},
    {"operation":"or","id":3,"colName":"id","expression":"equal","value":"200","evaluated":false}]*/
    //if (false && true) || false
    //logic is probably wrong but just:
    //group by operation
    var opgrouped = _.groupBy(uiSelectionResultsArr, 'operation');
    //console.log("op grouped: "+JSON.stringify(opgrouped));
    //add undefined group to whatever the group the second is in
    //there is only ever 1 element in the "undefined" group the top row
    if(sorted.length > 1){
      if(sorted[1].operation === "and"){
        opgrouped.and.push(opgrouped["undefined"][0]);
      }else{
        opgrouped.or.push(opgrouped["undefined"][0]);
      }
    }else{//single condition filter in which case just stick it in a new and group
      opgrouped.and = [];
      opgrouped.and.push(opgrouped["undefined"][0]);
    }
    //condense each group to single boolean each
    var condensedAnd = true, condensedOr = false;
    if(opgrouped.and){
      for(var x=0;x<opgrouped.and.length;x++){
        var cond = opgrouped.and[x];
        //console.log("opgrouped.and[x]: where x: "+x+", opgrouped.and[x]: "+JSON.stringify(opgrouped.and[x]));
        //console.log("cond.evaluated: "+cond.evaluated);
        if(cond.evaluated !== true){
          condensedAnd = false;
          break;
        }
      }
    }

    if(opgrouped.or){
      for(var y=0;y<opgrouped.or.length;y++){
        var cond = opgrouped.or[y];
        if(cond.evaluated === true){
          condensedOr = true;
          break;
        }
      }
    }
    //condense single booleans using or
    var result;
    if(opgrouped.and && opgrouped.or){
      result = (condensedAnd || condensedOr);
    }else if(opgrouped.or){
      result = condensedOr;

    }else if(opgrouped.and){
      result = condensedAnd;
    }

    if(result === true){
      console.log("boolean result: "+result+" adding row: "+JSON.stringify(row)+" to filteredData");
      filteredData.push(row);
    }

    //if(i>10)break;//for testing
  }

  hot.loadData(filteredData);
  $.modal.close();

});

这种逻辑有效,但我不能帮助感觉它不完美,或许有人可以提出一些改进建议

0 个答案:

没有答案