JavaScript:使一个值对数组形成一个值数组

JavaScript:使一个值对数组形成一个值数组,javascript,arrays,functional-programming,underscore.js,lodash,Javascript,Arrays,Functional Programming,Underscore.js,Lodash,是否有一种优雅、实用的方法来改变此阵列: [1,5,9,21] 进入这个 [[1,5],[5,9],[9,21] 我知道我可以forEach数组并收集值以创建新数组。在.lodash中是否有一种优雅的方法可以做到这一点,而无需使用forEach?您可以映射拼接阵列并检查索引。如果它不是零,则取前置数组,否则取原始数组的第一个元素 var数组=[1,5,9,21], 结果=数组.slice(1).map((a,i,aa)=>[i?aa[i-1]:数组[0],a]); 控制台日志(结果) .as控

是否有一种优雅、实用的方法来改变此阵列:

[1,5,9,21]

进入这个

[[1,5],[5,9],[9,21]


我知道我可以
forEach
数组并收集值以创建新数组。在
.lodash
中是否有一种优雅的方法可以做到这一点,而无需使用
forEach

您可以映射拼接阵列并检查索引。如果它不是零,则取前置数组,否则取原始数组的第一个元素

var数组=[1,5,9,21],
结果=数组.slice(1).map((a,i,aa)=>[i?aa[i-1]:数组[0],a]);
控制台日志(结果)

.as控制台包装{max height:100%!important;top:0;}
使用
map
的快速方法是:

const arr=[1,5,9,21];
const group=arr.map((el,i)=>[el,arr[i+1]])切片(0,-1);
控制台日志(分组)

.as控制台包装{max height:100%!important;top:0;}
如果您愿意使用另一个函数库“ramda”,这就是您要寻找的函数

使用示例取自ramda文档:

R.aperture(2, [1, 2, 3, 4, 5]); //=> [[1, 2], [2, 3], [3, 4], [4, 5]]
R.aperture(3, [1, 2, 3, 4, 5]); //=> [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
R.aperture(7, [1, 2, 3, 4, 5]); //=> []

这可以通过
数组轻松完成。减少
。下面所做的是使用数组作为聚合器,跳过第一个项,然后对于之后的每个项,将前一个项和当前项成对地推送到数组中

const arr=[1,5,9,21];
const chunked=arr.reduce((p,c,i,a)=>i==0?p:(p.push([c,a[i-1]]),p),[]);

console.log(分块)
我注意到当前的解决方案在某种程度上都是向前看或向后看的(
arr[I+1]
arr[I-1]

探索一种使用
reduce
和在函数闭包中定义的附加数组来存储待完成分区的方法可能也很有用

注:

  • 不是一行,但希望很容易理解
  • 当只处理2个项目时,
    part
    不必是数组,但通过使用数组,我们将该方法扩展到处理
    n
    大小的项目集
  • 如果你不喜欢
    shift
    ,你可以结合使用
    切片
    和重新定义
    部分
    ,但我认为这是安全的
  • 不返回
    长度小于所需元素数的分区
const partition=partitionSize=>arr=>{
常量部分=[];
返回arr.reduce((部分,x)=>{
第二部分:推(x);
if(part.length==分区大小){
parts.push(part.slice());
部分。移位();
}
返回部件;
}, []);
};
const makePairs=分区(2);
const makeTrios=分区(3);
常量对=生成对([1,2,3,4,5,6]);
常量三元组=最大三元组([1,2,3,4,5,6]);
log(“分区(2)”,JSON.stringify(对));

log(“分区(3)”,JSON.stringify(trios))
您可以只使用
.reduce()
的单音行,而不使用首字母

var arr=[1,5,9,21],
pairs=arr.reduce((p,c,i)=>i==1?[[p,c]]:p.concat([[p[p.length-1][1],c]]);

控制台日志(对)我确信在编程上有一种优雅的方法,但在数学上,我忍不住发现每一对新数组与原始数组的索引差为1

如果(稍后)需要将数组
[1,5,9,21,33]
转换为
[[1,9],[5,21],[9,33]
,则可以使用索引之间的差值为2这一事实


如果您为索引差1创建代码,那么扩展它就很容易了。

这里是
幻灯片
,它有两个参数来控制切片的大小以及切片之间删除的元素数量

幻灯片
与此处的其他答案不同,它为您提供了这些控制参数。这里的其他答案仅限于生成2的切片,或者每次将切片增加1

//take::(Int[a])->[a]
常量take=(n,xs)=>
xs.slice(0,n)
//删除::(Int[a])->[a]
常量下降=(n,xs)=>
xs.slice(n)
//切片::(Int,Int[a])->[[a]]
常量幻灯片=(m,n,xs)=>
xs.length>m
? [拍摄(m,xs),…幻灯片(m,n,drop(n,xs))]
:[xs]
常数arr=[0,1,2,3,4,5,6]
//日志帮助器提高了堆栈代码段中输出的可读性
const log=x=>console.log(JSON.stringify(x))
日志(幻灯片(1,1,arr))
// [[0],[1],[2],[3],[4],[5],[6]]
日志(幻灯片(1、2、arr))
// [[0],[2],[4],[6]]
日志(幻灯片(2、1、arr))
// [[0,1],[1,2],[2,3],[3,4],[4,5],[5,6]]
日志(幻灯片(2、2、arr))
// [[0,1],[2,3],[4,5],[6]]
日志(幻灯片(3、1、arr))
// [[0,1,2],[1,2,3],[2,3,4],[3,4,5],[4,5,6]]
日志(幻灯片(3、2、arr))
// [[0,1,2],[2,3,4],[4,5,6]]
日志(幻灯片(3,3,arr))

//[[0,1,2],[3,4,5],[6]
您为什么想要这个?你的目标是什么?。顺便说一句,该操作的名称通常被称为
分区
,该链接是谷歌第一次点击“lodash分区数组”。@niceman-该函数最好被称为“相邻对”——我以前使用过这个概念。贾里德·史密斯——这不一样。看看OPexample@TreeNguyen这不是一个完全重复的问题,而是一个类似的问题,这个问题只需要迭代,OP在这里想要返回一个新的array@aaaaaa是的,我一直在努力学习,所以用硬/可读的方式做事是我的道路。否则-ramda解决方案将完美无瑕。仍然是最可读的,也可以被其他队友理解。@Norris我终于删除了
pop
指令。现在代码更优雅了。拉姆达看起来真的很不错。与lodash/fp相比,我更喜欢它,但是维护人员不太活跃,他们花了很多时间讨论而不是编码。选择你的毒药:)谢谢,这看起来是除了使用Ramda之外最干净的方法。为什么不只是
(a,i)=>[array[i],a]
?这对空数组不起作用。为什么不仅仅是你