javascript - arrayOfFunctions.ForEach( Func.Every( 将参数传递到数组函数中) )

标签 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>

最佳答案

使用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));

关于javascript - arrayOfFunctions.ForEach( Func.Every( 将参数传递到数组函数中) ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46896129/

相关文章:

javascript - 尝试用圆圈创建图案?

javascript - Jquery\JS - 从输入字段创建对象数组时遇到问题

javascript - 不能使用 fnReloadAjax 数据表

javascript - 使用 PHP、JQuery 和 AJAX 从数据库获取 JSON 格式的数据

javascript - JS+IE9(默认安全): Redirect automatically to clickonce application

javascript - 仅在 Internet Explorer 中显示 Div(所有版本)

php - JS 中的开源国家/地区选择器

javascript - 如何防止提交后浏览器跳转到另一个页面?

javascript - jquery 显示超时倒计时输出

javascript - 固定在视口(viewport)下方并在视口(viewport)中滚动一次的菜单?