Javascript 按值对相邻数组项进行分组的最佳方法

Javascript 按值对相邻数组项进行分组的最佳方法,javascript,arrays,functional-programming,Javascript,Arrays,Functional Programming,假设我们有一个值数组: [5, 5, 3, 5, 3, 3] 按值和邻接度对它们进行分组的最佳方式是什么。结果如下: [ [5,5], [3], [5], [3,3] ] 当然,我可以在源数组中循环查找下一个/上一个项目,如果它们相同,则将它们推送到一个临时数组,然后将其推送到结果数组中 但我喜欢用函数的方式编写代码。所以也许有更好的方法?您可以使用以下方法: var result=[5,5,3,5,3,3].reduce(函数(prev,curr){ if(prev.length&&cu

假设我们有一个值数组:

[5, 5, 3, 5, 3, 3]
按值和邻接度对它们进行分组的最佳方式是什么。结果如下:

[ [5,5], [3], [5], [3,3] ]
当然,我可以在源数组中循环查找下一个/上一个项目,如果它们相同,则将它们推送到一个临时数组,然后将其推送到结果数组中

但我喜欢用函数的方式编写代码。所以也许有更好的方法?

您可以使用以下方法:

var result=[5,5,3,5,3,3].reduce(函数(prev,curr){
if(prev.length&&curr===prev[prev.length-1][0]){
prev[prev.length-1]。推送(当前);
}
否则{
上推([当前]);
}
返回上一个;
}, []);

警报(JSON.stringify(result))如果您谈论的是性能,那么n-复杂性[O(n)]就是您将得到的(您正在谈论的一次迭代)


如果您正在谈论内存使用优化,那么您可能希望推送/弹出对象(而不是复制它们)。或者尝试在首次创建输入数组时将其组织为数组数组(例如[5]、[5]、[3]、[5]、[3]、[5]、[3])并仅处理此数组,以将其形状设置为目标的最终形式


如果你想在你的实现中更别致一些,你可以尝试实现一个递归函数来处理它(但一般来说,在提供相同性能的两个实现之间,一个简单易读的就是你应该追求的),但按每个值(而不是值本身)的函数进行分组。比如说,

[1, 3, 5, 2, 4, 6, 7, 8, 9, 10, 42]
成为

[[1, 3, 5], [2, 4, 6], [7], [8], [9], [10, 42]]
给定分组函数

function (a) { return a % 2; }
一种方法是扩展@dfsq的方法,但使用字典范围的
fn_prev
来避免重新计算先前的
fn(val)

我觉得避免使用
.reduce
更为直接:

let fn_prev = null;
let acc = [];
for (let val of myArray) {
  let fn_curr = fn(val);
  if (!acc.length || fn_curr !== fn_prev) {
    acc.push([val]);
  } else {
    acc[acc.length - 1].push(val);
  }
  fn_prev = fn_curr;
}
console.log(acc);
这可以添加到阵列原型中,如下所示:

Object.defineProperty(Array.prototype, 'groupByAdjacent', {
  value: function(fn) {
    let fn_prev = null;
    let acc = [];
    for (let val of [].concat(this)) {
      let fn_curr = fn(val);
      if (!acc.length || fn_curr !== fn_prev) {
        acc.push([val]);
      } else {
        acc[acc.length - 1].push(val);
      }
      fn_prev = fn_curr;
    }
    return acc;
  }
});
使用方法如下:

let x = [1, 3, 5, 2, 4, 6, 7, 8, 9, 10, 42];
let grouped_x = x.groupByAdjacent(a => a % 2);
console.log(grouped_x);

这是不常见的
Array.prototype.reduceRight
-

const数据=
[ 5, 5, 3, 5, 3, 3 ]
const groupnextant=(a=[])=>
a、 还原光
(([组=[],…结果],v)=>
组长度
?组[0]==v
?[[v,…组],…结果]//v匹配组
:[[v],组,…结果]//v与组不匹配
:[[v],…结果]//没有要比较的组
, [[]]
)
console.log(组相邻(数据))
// [ [ 5, 5 ], [ 3 ], [ 5 ], [ 3, 3 ] ]
console.log(groupnextendent([]))

//[[]]
关于此代码的一些注意事项:
prev
是迄今为止构建的阵列的一部分,
curr
是我们正在查看的元素。我们要么添加到分组数组中的最后一个数组,要么启动一个新数组
prev.length
如果为0,则计算结果为false,这会阻止我们在第一次迭代中访问索引-1。
let x = [1, 3, 5, 2, 4, 6, 7, 8, 9, 10, 42];
let grouped_x = x.groupByAdjacent(a => a % 2);
console.log(grouped_x);