数组操作

123 阅读2分钟

一、 两个数组的交叉合并

var ary=["A","B","C","D"];
var ary2=[1,2,3,4,5,6];
function aryJoinAry(ary,ary2) {
    var itemAry=[];
    var minLength;
    //先拿到两个数组中长度较短的那个数组的长度
    if(ary.length>ary2.length){
        minLength=ary2.length;
    }
    else{
        minLength=ary.length;
    }
    //将两个数组中较长的数组记录下来
    var longAry=arguments[0].length>arguments[1].length?arguments[0]:arguments[1];
    //循环范围为较短的那个数组的长度
    for (var i = 0; i < minLength; i++) {
        //将数组放入临时数组中
        itemAry.push(ary[i]);
        itemAry.push(ary2[i])
    }
    //itemAry和多余的新数组拼接起来并返回。
    return itemAry.concat(longAry.slice(minLength));
}
console.log(aryJoinAry(ary, ary2));// ["A", 1, "B", 2, "C", 3, "D", 4, 5, 6]

二、两个数组合并成一个对象数组

有这么两个数组

 1 let metrodates = [
 2  "2008-01",
 3  "2008-02",
 4  "2008-03",..ect
 5 ];
 6 let figures = [
 7  0,
 8  0.555,
 9  0.293,..ect
10 ]

想要这样的结果

1 let result = [
2    {data: 0, date: "2008-01"},
3    {data: 0.555, date: "2008-02"},
4    {data: 0.293, date: "2008-03"},..ect
5 ];

方案一

1 let result = [];
2 for(let index in metrodates){
3     result.push({data: figures[index], date: metrodates[index]});
4 }

此方案为最原始方法,简单,但过于low

方案二

1 let result = metrodates.map((date,i) => ({date, data: figures[i]}));

此方案使用了ES6中的map,简洁,但本质还是遍历,显得有些low

方案三

1 const zip = ([x,...xs], [y,...ys]) => {
2   if (x === undefined || y === undefined)
3     return [];
4   else
5     return [[x,y], ...zip(xs, ys)];
6 }
7 let result = zip(metrodates, figures).map(([date, data]) => ({date, data}));

此方案使用了ES6+递归,显得高大上起来了。

方案四

 1 const isEmpty = xs => xs.length === 0;
 2 const head = ([x,...xs]) => x;
 3 const tail = ([x,...xs]) => xs; 
 4 const map = (f, ...xxs) => {
 5   let loop = (acc, xxs) => {
 6     if (xxs.some(isEmpty))
 7       return acc;
 8     else
 9       return loop([...acc, f(...xxs.map(head))], xxs.map(tail));
10   };
11   return loop([], xxs);
12 }
13 let result = map((date, data) => ({date, data}), metrodates, figures);

此方案是方案三的加强版,它能接受多个数组映射成对象数组,威力无比!