如何在javascript中创建分区函数.使用以下准则

How to create a partition function in javascript. using the following guidelines

本文关键字:函数 分区 javascript 创建      更新时间:2023-09-26

我一直在尝试创建一个返回数组数组的通用分区函数。 应根据以下准则创建该函数:
参数:

  1. 一个数组
  2. 一个函数

目标:

  1. 中的每个元素调用 ,并向其传递参数:

    element, key, <array>
    
  2. 返回一个由 2 个子数组组成的数组:

     0.一个数组,包含 返回真实内容
    的所有值 1.一个数组,包含 返回错误内容的所有值

这是我到目前为止所拥有的。我得到两个的回报。我觉得也许我只需要在两个不同的场合做过滤功能,但我不确定如何把它放在一起。非常感谢您的想法和建议。

_.partition = function (collection, test){
    var allValues = [];
    var matches = [];
    var misMatches = [];
    _.filter(collection.value, function(value, key, collection){
      if (test(value[key], key, collection) === "string"){
        matches.push(value[key]);
      }else{
        misMatches.push(value[key]);
      }
    });
  return allValues.push(matches, misMatches);
}

这是一个使用 reduce 的版本:

function partition(arr, filter) {
  return arr.reduce(
    (r, e, i, a) => {
      r[filter(e, i, a) ? 0 : 1].push(e);
      return r;
    }, [[], []]);
}

这是一个替代版本,它使用 Array#filter 来查找匹配项,并在此过程中构建一组非匹配项:

function partition(arr, filter) {
  var fail = [];
  var pass = arr.filter((e, i, a) => {
    if (filter(e, i, a)) return true;
    fail.push(e);
  });
  return [pass, fail];
}

在不同场合调用 filter 方法是正确的。一次filter调用将获得真实值;另一个将获得虚假值:

_.partition = function(collection, testFunc) {
  var matches = collection.filter(function(elem) {
    return test(elem) === 'string';
  });
  var misMatches = collection.filter(function(elem) {
    return test(elem) !== 'string';
  });
  return [matches, misMatches];
}

你很接近,但我看到有几个问题:

  1. 您返回的结果不是allValues本身allValues.push,而是数组的新长度。
  2. 您正在使用_.filter遍历数组元素并将它们排序为两个数组。这很奇怪,因为它不是_.filter的预期用途。

如果您想要一个使用 _.filter 的快速且可读的解决方案,这将起作用:

_.mixin({
  partition: function(collection, test) {
    return [
      _.filter(collection, test),  // items which satisfy condition
      _.filter(collection, _.negate(test))  // items which don't
    ];
  }
});

下面有一个更有效的解决方案,它只对集合进行一次传递(这几乎是你已经拥有的):

_.mixin({
  partition: function(collection, test) {
    var matches = [], misMatches = [], value;
    // can replace this loop with _.each
    for (var i = 0, len = collection.length; i < len; ++i) {
      value = collection[i];
      // push the value into the appropriate array
      if (test(value, i, collection)) {
        matches.push(value);
      } else {
        misMatches.push(value);
      }
    }
    return [matches, misMatches];
  }
});

使用示例(和 Plunker):

function isOdd(x) {
  return x % 2;
}
// _.mixin allows you to do either one of these
_.partition([1, 2, 3, 4, 5, 6], isOdd);  // result: [[1, 3, 5], [2, 4, 6]]
_([1, 2, 3, 4, 5, 6]).partition(isOdd);  // result: [[1, 3, 5], [2, 4, 6]]
// this is a use case you brought up in the comments
_.partition([1, "a", 2, "b", 3, "c"], _.isString);  // result: [["a", "b", "c"], [1, 2, 3]]

在函数式语言中通常被称为partition。你将一个数组(xs)和一个谓词函数(p)与初始值为[[],[]]reduce函数相提并论。

var partition = (xs,p) => xs.reduce( (r,e) => ( p(e) ? r[0].push(e)
                                                     : r[1].push(e)
                                              , r
                                              )
                                   , [[],[]]
                                   );

这样;

> partition([1,2,3,4,5,6,7,8,9,0], x => x < 5)
> [[1, 2, 3, 4, 0],[5, 6, 7, 8, 9]]