arrayOfFunctions.ForEach(Func.Every(将参数传递给数组函数))

时间:2017-10-23 18:29:02

标签: javascript

下面我的示例有效,但它不是模块化的,带有硬编码的“switch”语句,用于确定我的函数数组中存在多少函数。

我试图弄清楚如何使用forEach()和every()但是我遇到了将参数传递给数组中包含的函数的麻烦。 (至少这是我在这一点上的假设......

以下不起作用?

_this.oData.forEach(function (oRow) {
    function foo(checksArray) {
        var meetsAll = fc.every(function (func,oRow) {
            return func(oRow);
        });
        console.log(meetsAll);
        if (meetsAll){
                _this.oFiltered.push(oRow);
        };
    };
});

这是一个完整的工作样本,但不正确,因为不是模块化的。

_this = this;
// sample data
_this.oData = [
    { 'itemfk': 123, 'vdrfk': 24 },
    { 'itemfk': 13, 'vdrfk': 34 },
    { 'itemfk': 18, 'vdrfk': 77 },
    { 'itemfk': 13, 'vdrfk': 24 },
    { 'itemfk': 48, 'vdrfk': 34 }
];
_this.oItemsSelected = [
    { 'itemfk': 123 },
    { 'itemfk': 13 }
];
_this.oVendorsSelected = [
    { 'vdrfk': 234 },
    { 'vdrfk': 24 }
];


// called by cascading controls
this.filterConditions = function () {

    // build test conditions into array of functions
    var fc = [];
    // items condition
    if (_this.oItemsSelected.length > 0) {

        fc.push(
            function (oRow) {
                for (var nItem = 0; nItem < _this.oItemsSelected.length; nItem++) {
                    //console.log(_this.oItemsSelected[nItem].itemname +' row '+ oRow.itemname);
                    if (_this.oItemsSelected[nItem].itemfk === oRow.itemfk) {
                        return true;
                    }
                };
                return false;
            }
        );

    };
    // vendors condition
    if (_this.oVendorsSelected.length > 0) {

        fc.push(
            function (oRow) {
                for (var nVendor = 0; nVendor < _this.oVendorsSelected.length; nVendor++) {
                    if (_this.oVendorsSelected[nVendor].vdrfk === oRow.vdrfk) {
                        return true;
                    }
                };
                return false;
            }
        );
    };

    // loop data and apply conditions
    _this.oFiltered = [];
    _this.oData.forEach(function (oRow) {

        switch (fc.length) {
            case 1:
                if (fc[0](oRow)) {
                    _this.oFiltered.push(oRow);
                };
                break;
            case 2:
                if (fc[0](oRow) && fc[1](oRow)) {
                    _this.oFiltered.push(oRow);
                };
                break;
        };
    });

    // two oData rows (index zero and three) match conditions
    console.log(_this.oFiltered); 

};

任何帮助将不胜感激!

_this = this;
// sample data
_this.oData = [
    { 'itemfk': 123, 'vdrfk': 24 },
    { 'itemfk': 13, 'vdrfk': 34 },
    { 'itemfk': 18, 'vdrfk': 77 },
    { 'itemfk': 13, 'vdrfk': 24 },
    { 'itemfk': 48, 'vdrfk': 34 }
];
_this.oItemsSelected = [
    { 'itemfk': 123 },
    { 'itemfk': 13 }
];
_this.oVendorsSelected = [
    { 'vdrfk': 234 },
    { 'vdrfk': 24 }
];


// called by cascading controls
this.filterConditions = function () {

    // build test conditions into array of functions
    var fc = [];
    // items condition
    if (_this.oItemsSelected.length > 0) {

        fc.push(
            function (oRow) {
                for (var nItem = 0; nItem < _this.oItemsSelected.length; nItem++) {
                    //console.log(_this.oItemsSelected[nItem].itemname +' row '+ oRow.itemname);
                    if (_this.oItemsSelected[nItem].itemfk === oRow.itemfk) {
                        return true;
                    }
                };
                return false;
            }
        );

    };
    // vendors condition
    if (_this.oVendorsSelected.length > 0) {

        fc.push(
            function (oRow) {
                for (var nVendor = 0; nVendor < _this.oVendorsSelected.length; nVendor++) {
                    if (_this.oVendorsSelected[nVendor].vdrfk === oRow.vdrfk) {
                        return true;
                    }
                };
                return false;
            }
        );
    };

    // loop data and apply conditions
    _this.oFiltered = [];
    _this.oData.forEach(function (oRow) {

        switch (fc.length) {
            case 1:
                if (fc[0](oRow)) {
                    _this.oFiltered.push(oRow);
                };
                break;
            case 2:
                if (fc[0](oRow) && fc[1](oRow)) {
                    _this.oFiltered.push(oRow);
                };
                break;
        };
    });

    // two oData rows (index zero and three) match conditions
    console.log(_this.oFiltered); 

};
<html>
<head>
    <title></title>
	<meta charset="utf-8" />
    <script src="https://stacksnippets.net/js"></script>
</head>
<body onload="filterConditions()">

</body>
</html>

2 个答案:

答案 0 :(得分:1)

使用Array.prototype.every()的方式是:

_this.oFiltered = _this.oData.filter(function (oRow) {
  return fc.every(function(func) {
    return func(oRow);
  });
});

如果你替换它:

// loop data and apply conditions
_this.oFiltered = [];
_this.oData.forEach(function (oRow) {

    switch (fc.length) {
        case 1:
            if (fc[0](oRow)) {
                _this.oFiltered.push(oRow);
            };
            break;
        case 2:
            if (fc[0](oRow) && fc[1](oRow)) {
                _this.oFiltered.push(oRow);
            };
            break;
    };
});

在此答案的基础上使用代码段,您就完成了。

我冒昧地在以下代码段中调整您的脚本 - 使用closure和更多Array.prototype.*方法。这可能会有点令人困惑,但也许有一些有用/有趣的东西:)

_this = {};
_this.oData = [{'itemfk':123,'vdrfk':24},{'itemfk':13,'vdrfk':34},{'itemfk':18,'vdrfk':77},{'itemfk':13,'vdrfk':24},{'itemfk':48,'vdrfk':34}];
_this.oItemsSelected = [{'itemfk':123},{'itemfk':13}];
_this.oVendorsSelected = [{'vdrfk':234},{'vdrfk':24}];


function createFilterFunction( /* conditions */ ) {
  var conditions = Array.prototype.slice.apply(arguments), // convert <arguments> into a real array so we can use <Array.prototype.map()>
      fc = conditions.map(function(condition) {
        // we create a new function for each "condition" passed as parameter
        return function(row) {
          // <Array.prototype.some()> returns true if one of the items in the array fulfills the predicate
          return condition.data.some(function(item) {
            return item[condition.key] === row[condition.key];
          });
        };
      });

  // the "actual" function to filter the passed data
  return function(dataToFilter) {
    return dataToFilter.filter(function(data) {
      // here we call every filter function in <fc> with every element in <dataToFilter> until one of the elements doesn't fulfill the predicate
      return fc.every(function(func) {
        return func(data);
      })
    });
  };
}

// setup the function to filter the data
var filterConditions = createFilterFunction(
   // <data> = items for comparison
   // <key>  = name of the property whose value should be compared
   { data: _this.oItemsSelected,   key: "itemfk" }
  ,{ data: _this.oVendorsSelected, key: "vdrfk" }
  // third condition
  // fourth condition
  // ...
);


var filteredConditions = filterConditions(_this.oData);
console.log(JSON.stringify(filteredConditions));

答案 1 :(得分:0)

您可以尝试使用map和forEach方法,下面给出了工作演示

&#13;
&#13;
_this = this;
// sample data
_this.oData = [{
    'itemfk': 123,
    'vdrfk': 24
  },
  {
    'itemfk': 13,
    'vdrfk': 34
  },
  {
    'itemfk': 18,
    'vdrfk': 77
  },
  {
    'itemfk': 13,
    'vdrfk': 24
  },
  {
    'itemfk': 48,
    'vdrfk': 34
  }
];
_this.oItemsSelected = [{
    'itemfk': 13
  },
  {
    'itemfk': 123
  }
];
_this.oVendorsSelected = [{
    'vdrfk': 234
  },
  {
    'vdrfk': 24
  }
];
// called by cascading controls
this.filterConditions = function() {
  var arr = _this.oItemsSelected.map(function(element) {
    return Object.values(element)[0]
  });
  var arr2 = _this.oVendorsSelected.map(function(element) {
    return Object.values(element)[0]
  });
  _this.oData.forEach(function(element) {
    if (arr.indexOf(element.itemfk) != -1 && arr2.indexOf(element.vdrfk) != -1) {
      console.log(element);
    }
  });
  // two oData rows (index zero and three) match conditions


};



<!-- begin snippet: js hide: false console: true babel: false -->
&#13;
<html>

<head>
  <title></title>
  <meta charset="utf-8" />
  <script src="https://stacksnippets.net/js"></script>
</head>

<body onload="filterConditions()">

</body>

</html>
&#13;
&#13;
&#13;