javascript(函数式编程思考) ---> Map-Filter-quicksort-Collatz序列-Flodl-Flodr

let add = x=>x+1;


//Map :: ( a -> b) -> [a] -> [b]
let Map = function(f,arr){
    //闭包存储累积对象
    let result = [];
    return function map(f,arr){
            if(!Array.isArray(arr)){
                return "要处理的对象为数组";
            }
            if(arr.length ==0){
                return [];
            }else{
                let [head,...tail] = arr;
                result.push(f(head));
                // 通过回调map遍历目标对象arr,f处理过的元素存入result,tail为[]即遍历结束,可以返回result
                return tail.length == 0 ? result : map(f,tail);
            }
    }(f,arr);
};
let test = Map(add,[1,2,3]);
console.log(test);//[2,3,4]

 

 

let biggerTen = x => x>10;
//Filter :: (a -> Bool) -> [a] -> [a]
let Filter = function(f,arr){
    let result=[];
    return function filter(f,arr){
            if(!Array.isArray(arr)){
                return "要处理的对象为数组";
            }
            if(arr.length == 0){
                return [];
            }else{
                let [head,...tail] = arr;
                if(f(head)){
                    result.push(head)
                }
                return tail.length == 0 ? result : filter(f,tail);
            }
    }(f,arr);
};

let testFilter = Filter(biggerTen,[1,5,10,44,12,2,5]);
console.log(testFilter);//[44,12]

 

快速排序:

let small  = x=>y=>y <=x;
let bigger = x=>y=>y > x;
console.log(Filter(bigger(5),[7,2,1,4]));
console.log(Filter(small(5),[7,2,1,4]));

//QuickSort :: (Ord a) => [a] -> [a]
let QuickSort = (function(){
    return function quickSort(arr){
        if(arr.length == 0){
            return [];
        }else{
            let [head,...tail] = arr;
            let smallerSorted = quickSort(Filter(small(head),tail));
            let biggerSorted  = quickSort(Filter(bigger(head),tail));
            return smallerSorted.concat([head]).concat(biggerSorted);
        }
    };
})();

let testQuickSort = QuickSort([5,7,2,1,4]);
console.log(testQuickSort);//[1,2,4,5,7]

 

Collatz序列:

let div2  = x=>x/2;
let someF = x=>x*3+1;

const Chain = function(n){
    let result=[];
    return function chain(n){
        result.push(n);
        if(n == 1){return [1]}
        let even = n%2 ==0 ? chain( div2(n) )  : [];
        let odd  = n%2 !=0 ? chain( someF(n))  : [];
        return result;
    }(n);
};
console.log(Chain(10));//[10,5,16,8,4,2,1]

 

Foldl:

// 左折叠
const Foldl = function(f,list,initValue){
    if(list.length == 0){
        return initValue || null;
    }else{
        let accumulated=initValue || list.shift() ;
        let foldl = function(acc,x){
            accumulated = f(acc,x);
            return list.length==0 ? accumulated : foldl(accumulated,list.shift()); 
        }
        return list.length==0 ? accumulated : foldl(accumulated,list.shift());        
    }
}

let reducer = (x,y) => (x+y);
let reducerMultiply = (x,y) => x*y;
console.log(Foldl(reducer,[1,2,3]));//6
console.log(Foldl(reducerMultiply,[2,3,4]));//24

Foldr:

// 右折叠
const Foldr = function(f,list,initValue){
    if(list.length == 0){
        return initValue || null;
    }else {
        let accumulated = initValue || list.pop();
        let foldr = function(x,acc){
            accumulated = f(x,acc);
            return list.length==0 ? accumulated : foldr(list.pop(),accumulated);
        }
        return list.length==0 ? accumulated : foldr(list.pop(),accumulated);
    }
}

let reverse = (x,y) => {
    y.push(x); 
    return y;
};

console.log(Foldr(reverse,[1,2,3],[]));//[3,2,1]

用Fold重新创建新的Map和Filter:

// 用Foldr创建新的Filter 当然也可以用Foldl
const newFilter = function(f,list){
    let condition = function(x,acc){
        f(x) && acc.push(x);
        return acc;
    }
    let result = Foldr(condition,list,[]);
    return Foldr(reverse,result,[]);
}

let bigger20 = x=>x>20;

console.log(newFilter(bigger20,[10,22,50,1,41,2])); // [22,50,41]

// 用Foldl 创建新的Map
const newMap = function(f,list){
    let map = function(acc,x){
        acc.push(f(x));
        return acc;
    }
    return Foldl(map,list,[]);
}
let addTwo = x => x+2;
console.log(newMap(addTwo,[1,2,3]));//[3,4,5]

 

posted @ 2017-08-26 15:37  烂拖鞋  阅读(251)  评论(0编辑  收藏  举报