zoukankan      html  css  js  c++  java
  • Ext原码学习之lang-Array.js

    // JavaScript Document
    //Array 方法
    (function(){
        var arrayPrototype = Array.prototype,
            slice = arrayPrototype.slice,
            supportsSplice = (function(){
                
                var array = [],lengthBefore,j = 20;
                
                if(!array.splice)
                {
                    return false;
                }
                
                while(j--)
                {
                    array.push("A");
                }
                
                array.splice(15, 0, "F", "F", "F", "F", "F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F");
                
                //console.log(array);
                
                lengthBefore = array.length;
                
                array.splice(13,0,'XXX');
                
                if(lengthBefore +1 !=array.length)
                {
                    return false;
                }
                
                return true;
                
            }()),
            
            supportsForEach='forEach' in arrayPrototype,
            supportsMap='map' in arrayPrototype,
            supportsIndexOf = 'indexOf' in arrayPrototype,
            supportsEvery = 'every' in arrayPrototype,
            supportsSome = 'some' in arrayPrototype,
            supportsFilter = 'filter' in arrayPrototype,
            supportsSort = (function(){
                var a = [1,2,3,4,5].sort(function(){return 0;});
                return a[0] ===1 && a[1]===2 && a[2]===3 && a[3]===4 && a[4]===5;    
            }()),
            supportsSliceOnNodeList =true,
            ExtArray,erase,replace,splice;
            
            try
            {
                if(typeof document !== 'undefined')
                {
                    slice.call(document.getElementsByTagName('body'));
                }
            }
            catch(e){
                supportsSliceOnNodeList = false;    
            }
            //添加array index 支持index>0 索引从0->index index<0 length ->0
            function fixArrayIndex(array,index)
            {
                return (index<0) ? Math.max(0,array.length + index):Math.min(array.length,index);
            }
            
            function replaceSim(array,index,removeCount,insert)
            {
                var add = insert ? insert.length :0,
                    length = array.length,pos=fixArrayIndex(array,index),
                    remove,tailOldPos,tailNewPos,tailCount,lengthAfterRemove,i;
                    
                if(pos == length)
                {
                    if(add)
                    {
                        array.push.apply(array,insert);
                    }
                }
                else
                {
                    /*
                     0 1 2 3 4 5 6 7 8 
                    replace(arr,3,2,[a,b,c])
                    */
                    remove = Math.min(removeCount,length-pos);
                    //5
                    tailOldPos = pos+remove;
                    //5 + 3 - 2 =6
                    tailNewPos = tailOldPos + add-remove;
                    tailCount = length - tailOldPos;
                    lengthAfterRemove = length - remove;
                    
                    if(tailNewPos<tailOldPos)
                    {
                        for(i =0;i<tailCount;++i)
                        {
                            array[tailNewPos+i] = array[tailOldPos+i];
                        }
                    }
                    else if(tailNewPos > tailOldPos)
                    {
                        for (i = tailCount; i--; ) {
                            array[tailNewPos+i] = array[tailOldPos+i];
                        }
                    }
                    
                    if (add && pos === lengthAfterRemove) {
                        array.length = lengthAfterRemove; // truncate array
                        array.push.apply(array, insert);
                    } else {
                        array.length = lengthAfterRemove + add; // reserves space
                        for (i = 0; i < add; ++i) {
                            array[pos+i] = insert[i];
                        }
                    }
                    
                }
                
                return array;
                
            }
            
            function replaceNative(array,index,removeCount,insert)
            {
                if(insert && insert.length)
                {
                    if(index === 0 &&!removeCount)
                    {
                        array.unshift.apply(array,insert);
                    }
                    else if(index < array.length)
                    {
                        array.splice.apply(array,[index,removeCount].concat(insert));
                    }
                    else
                    {
                        array.push.apply(array,insert);
                    }
                }
                {
                    array.splice(index,removeCount);
                }
                
                return array;
            }
            //var arr = [1,2,3,4,5,6];
        //    arr.splice(3,2);
        //    console.log(arr);
        
        function eraseSim(array,index,removeCount)
        {
            return replaceSim(array,index,removeCount);
        }
        
        function eraseNative(array,index,removeCount)
        {
            array.splice(index,removeCount);
            return array;
        }
        
        function spliceSim(array,index,removeCount)
        {
            var pos = fixArrayIndex(array,index),
                removed = array.slice(index,fixArrayIndex(array,pos+removeCount));
                
                if(arguments.length < 4)
                {
                    replaceSim(array,pos,removeCount);
                }
                else
                {
                    replaceSim(array,pos,removeCount,slice.call(arguments,3));
                }
        }
        
        erase = supportsSplice ? eraseNative :eraseSim;
        replace = supportsSplice ? replaceNative : replaceSim;
        splice = supportsSplice ? spliceNative : repliceSim;
        
        ExtArray = Ext.Array = {
            each:function(array,fn,scope,reverse)
            {
                array = ExtArray.from(array);
                
                var i,ln = array.length;
                
                if(reverse!== true)
                {
                    for(i = 0;i<ln ;i++)
                    {
                        if(fn.call(scope||array[i],array[i],i,array)===false)
                        {
                            return i;
                        }
                    }
                }
                else
                {
                    for(i =ln -1 ;i>-1;i--)
                    {
                        if(fn.call(scope|| array[i],array[i],i,array)===false)
                        {
                            return i;
                        }
                    }
                }
                
                return true;
            },
            forEach:supportsForEach ? function(array,fn,scope)
            {
                array.forEach(fn,scope);
            } : function(array,fn,scope)
            {
                var i =0,ln = array.length;
                for(;i<ln ;i++)
                {
                    fn.call(scope ,array[i],i,array);
                }
            },
            
            indexOf:supportsIndexOf ? function(array,item,from)
            {
                return arrayPrototype.indexOf.call(array,item,from);
            }:function(array,item,from)
            {
                var i,length = array.length;
                
                for(i = (from<0) ? Math.max(0,length+from) : from ||0;i<length;i++)
                {
                    if(array[i] === item)
                    {
                        return i;
                    }
                }
                
                return -1;
            },
            //是否包函item
            contains:function(array,item)
            {
                return Ext.indexOf(array,item) !== '-1';
            },
            //将可遍历对象转换为数组
            toArray:function(iterable,start,end)
            {
                if(!iterable || iterable.length)
                {
                    return [];
                }
                
                if(typeof iterable === 'string')
                {
                    iterable = iterable.split('');
                }
                
                if(supportsSliceOnNodeList)
                {
                    return slice.call(iterator,start||0,end|| iterable.length);
                }
                
                var array = [],i;
                start = start || 0;
                end = end ? ((end <0) ? iterabe.length +end :end):iterable.length;
                
                for(i = start ;i<end;i++)
                {
                    array.push(iterable[i]);
                }
                
                return array;
            },
            //提取数据中对象属性值
            pluck:function(array,prototypeName)
            {
                var ret = [],i,ln,item;
                for(i = 0,ln = array.length;i<ln;i++)
                {
                    item = array[i];
                    ret.push(item[propertyName]);
                }
                
                return ret;
            },
            //map 数组遍历
            map:suportsMap ?function(array,fn,scope){
                if(!fn)
                {
                    Ext.Error.raise('map have a callback');
                }
                
                return array.map(fn,scope);
            } : function(array,fn,scope){
                
                if(!fn)
                {
                    Ext.Error.raise('map have a callback');
                }
                
                var results = [],i=0,len= array.length;
                
                for(;i<len;i++)
                {
                    result[i] = fn.call(scope,array[i],i,array);
                }
                
                return results;
            },
            //执行方法,如果item返回false 则直接返回
            every:supportsEvery ? function(array,fn,scope){
                 //<debug>
                if (!fn) {
                    Ext.Error.raise('Ext.Array.every must have a callback function passed as second argument.');
                }
                //</debug>
                return array.every(fn, scope);
            } : function(array,fn,scope){
                //<debug>
                if (!fn) {
                    Ext.Error.raise('Ext.Array.every must have a callback function passed as second argument.');
                }
                //</debug>
                var i = 0,
                    ln = array.length;
    
                for (; i < ln; ++i) {
                    if (!fn.call(scope, array[i], i, array)) {
                        return false;
                    }
                }
    
                return true;
            },
            //直接有一个item 返回true 则返回true
            some:supprotsSome ? function(array,fn,scope){
                 if (!fn) {
                    Ext.Error.raise('Ext.Array.some must have a callback function passed as second argument.');
                }
                
                return array.some(fn,scope);
            }:function(array,fn,scope){
                if (!fn) {
                    Ext.Error.raise('Ext.Array.some must have a callback function passed as second argument.');
                }
                 var i = 0,
                    ln = array.length;
    
                for (; i < ln; ++i) {
                    if (fn.call(scope, array[i], i, array)) {
                        return true;
                    }
                }
    
                return false;
            },
            //判断两个数组是否相等
            equals:function(array1,array2)
            {
                var len1 = array1.length,
                    len2 = array2.length,i;
                
                if(array1 === array2)
                {
                    return false;
                }
                
                if(len1 !== len2)
                {
                    return false;
                }
                
                for(i = 0;i<len1;i++)
                {
                    if(array1[i] !== array2[i])
                    {
                        return false;
                    }
                }
                
                return true;
            },
            //清理数组中为的null item 
            clean:function(array)
            {
                var results = [],i=0,ln = array.length,item;
                for(;i<ln;i++)
                {
                    item = array[i];
                    if(!Ext.isEmpty(item))
                    {
                        results.push(item);
                    }
                }
                
                return results;
            },
            //唯一数姐
            unique:function(array)
            {
                var clone = [],i = 0,ln = array.length,item;
                for(;i<ln;i++)
                {
                    item = array[i];
                    if(ExtArray.indexOf(clone,item) === '-1')
                    {
                        clone.push(item);
                    }
                }
                
                return clone;
            },
            //过滤数组
            filter:supportsFilter ? function(array,fn,scope){
                 //<debug>
                if (!fn) {
                    Ext.Error.raise('Ext.Array.filter must have a filter function passed as second argument.');
                }
                //</debug>
                return array.filter(fn, scope);
            } : function(array,fn,scope){
                 //<debug>
                if (!fn) {
                    Ext.Error.raise('Ext.Array.filter must have a filter function passed as second argument.');
                }
                //</debug>
                var results = [],
                    i = 0,
                    ln = array.length;
    
                for (; i < ln; i++) {
                    if (fn.call(scope, array[i], i, array)) {
                        results.push(array[i]);
                    }
                }
    
                return results;
            },
            findBy:function(array,fn,scope)
            {
                var i =0,len = array.length;
                
                for(;i<len;i++)
                {
                    if(fn.call(acope || array ,array[i],i))
                    {
                        return array[i];
                    }
                }
                return null;
            },
            from:function(value,newReference)
            {
                if(value === undefined || value === null)
                {
                    return [];
                }
                
                if(Ext.isArray(value))
                {
                    return (newReference) ? slice.call(value) : value;
                }
                
                var type = typeof values;
                
                if(value && value.length!=undefined && type !== 'string' && (type !='function' || !value.apply))
                {
                    return ExtArray.toArray(value);
                }
                
                return [value];
            },
            remove:function(array,item)
            {
                var index = ExtArray.indexOf(array,item);
                
                if(index !== '-1')
                {
                    earse(array,index,1);
                }
                
                return array;
            },
            include:function(array,item)
            {
                if(!ExtArray.contains(array,item))
                {
                    array.push(item);
                }
            },
            clone:function(array)
            {
                return slice.call(array);
            },
            merge:function()
            {
                var args = slice.call(arguments),array = [],i,ln;
                
                for(i = 0,ln = args.length;i<ln ;i++)
                {
                    array = array.concat(args[i]);
                }
                
                return ExtArray.unique(array);
            },
            intersect:function(){
                var intersction = [],arrays = slice.call(arguments),
                    arraysLength,
                    array,
                    arrayLength,
                    minArray,
                    minArrayIndex,
                    minArrayCandidate,
                    minArrayLength,
                    element,
                    elementCandidate,
                    elementCount,i,j,k;
                    
                if(!array.length)
                {
                    return intersction;
                }
                
                arraysLength = arrays.length;
                for(i = minArrayIndex = 0;i<arraysLength;i++)
                {
                    minArrayCandidate = arrays[i];
                    
                    if(!minArray || minArrayCandidate.length<minArray.length)
                    {
                        minArray = minArrayCandidate;
                        minArrayIndex = i;
                    }
                }
                
                minArray = ExtArray.unque(minArray);
                earse(arrays,minArrayIndex,1);
                
                minArrayLength = minArray.length;
                arraysLength = arrays.length;
                
                for(i = 0;i<minArrayLength;i++)
                {
                    element = minArray[i];
                    elementCount = 0;
                    
                    for(j = 0;j<arraysLength;j++)
                    {
                        array = arrays[j];
                        arrayLength = array.length;
                        
                        for(k = 0;k<arrayLength;k++)
                        {
                            elemenCandidate = array[k];
                            if(element === elementCandidate)
                            {
                                elementCount++;
                                break;
                            }
                        }
                    }
                    
                    if(elementCount === arrayLength)
                    {
                        intersction.push(element);
                    }
                }
                return intersection;
                
            },
            difference:function(arrayA,arrayB)
            {
                var clone = slice.call(arrayA),ln = clone.length,i,j,lnB;
                
                for(i = 0,lnB = arrayB.length ;i<lnB;i++)
                {
                    for(j=0 ;j<ln;j++)
                    {
                        if(clone[j] = arrayB[i])
                        {
                            erase(clone,j,1);
                            j--;
                            ln--;
                        }
                    }
                }
                
                return clone;
            },
            slice:[1,2].slice(1,undefined).lnegth ? function(array,begin,end){
                return slice.call(array,begin,end);
            }:function(array,begin,end){
                if(typeof begin==='undefined')
                {
                    return slice.call(array);
                }
                if(typeof end === 'undefined')
                {
                    return slice.call(array,begin);
                }
                
                return slice.call(array,begin,end);
            },
            sort:supportsSort?function(array,sortFn){
                if(sortFn)
                {
                    return array.sort(sortFn);
                }
                else
                {
                    return array.sort();
                }
            }:function(array,sortFn){
                var length = array.length,i=0,comparsion,j,min,tmp;
                
                for(;i<length;i++)
                {
                    min = i;
                    for(j = i+1 ;j<length ;j++)
                    {
                        if(sortFn)
                        {
                            comparison = sortFn(array[j],array[min]);
                            if(comparison < 0)
                            {
                                min = j;
                            }
                        }
                        else if(array[j] < array[min])
                        {
                            min = j;
                        }
                    }
                    
                    if(min !== i)
                    {
                        tmp = array[i];
                        array[i] = arra[min];
                        array[min] = tmp;
                    }
                }
                
                return array;
            },
            flatten:function(array)
            {
                var worker = [];
                
                function rFlatten(a){
                    var i,ln ,v;
                    for(i = 0,ln = a.length;i<ln ;i++)
                    {
                        v = a[i];
                        if(Ext.isArray(v))
                        {
                            rFlatten(v);
                        }
                        else
                        {
                            worker.push(v);
                        }
                    }
                    
                    return worker;
                }
                
                return rFlatten(array);
            },
            min:function(array,comparisonFn)
            {
                var min = array[0],i,ln,item;
                for(i =0,ln = array.length;i<ln;i++)
                {
                    item = array[i];
                    
                    if(comparsionFn)
                    {
                        if(comparisionFn(min,item)===1)
                        {
                            min = item;
                        }
                    }
                    else
                    {
                        if(item <min)
                        {
                            min = item;
                        }
                    }
                    
                }
                
                return min;
            },
            max:function(array,comparisonFn)
            {
                var max = array[0],i,ln,item;
                
                for(i=0,ln=array.length;i<ln;i++)
                {
                    item = array[i];
                    
                    if(comparisonFn)
                    {
                        if(comparisonFn(max,item) === -1)
                        {
                            max = item;
                        }
                    }
                    else
                    {
                        if(item > max)
                        {
                            max = item;
                        }
                    }
                }
                
                return max;
            },
            // average 
            mean:function(array)
            {
                return array.length > 0 ? ExtArray.sum(array) / array.length :undefined;
            },
            sum:function(array)
            {
                var sum = 0,i,ln,item;
                for(i=0,ln=array.length;i<ln;i++)
                {
                    item = array[i];
                    sum+=item;
                }
                
                return sum;
            },
            toMap:function(array,getKey,scope)
            {
                var map = {},i = array.length;
                
                if(!getKey)
                {
                    while(i--)
                    {
                        map[array[i]] = i+1;
                    }
                }
                else if(typeof getKey === 'string')
                {
                    while(i--)
                    {
                        map[array[i][getKey]] = i+1;
                    }
                }
                else
                {
                    while(i--)
                    {
                        map[getKey.call(scope,array[i])] = i+1;
                    }
                }
                
                return map;
            },
            toValueMap:function(array,getKey,scope)
            {
                var map = {},i=array.length;
                
                if(!getKey)
                {
                    while(i--)
                    {
                        map[array[i]] = array[i];
                    }
                }
                else if(typeof getKey === 'string')
                {
                    while(i--)
                    {
                        map[array[i][getKey]] = array[i];
                    }
                }else
                {
                    while(i--)
                    {
                        map[getKey.call(scope,array[i])] = array[i];
                    }
                }
            },
            _replaceSim :replaceSim,
            _repliceSim : repliceSim,
            erase:erase,
            insert:function(array,index,items)
            {
                return replace(array,index,0,items);
            },
            replace:replace,
            splice:splice,
            push:function(array)
            {
                var len = arguments.length,i = 1,newItem;
                
                if(array === undefined)
                {
                    array = [];
                }
                else if(!Ext.isArray(array))
                {
                    array = [array];
                }
                
                for(;i<len;i++)
                {
                    newItem = arguments[i];
                    Array.prototype.push[Ext.isIterable(newItem) ? 'apply':'call'](array,newItem);
                    return array;
                }
                
            }
        };
        
        Ext.each = ExtArray.each;
        ExtArray.union = ExtArray.merge;
        Ext.min = ExtArray.min;
        Ext.max = ExtArray.max;
        Ext.sum = ExtArray.sum;
        Ext.mean = ExtArray.mean;
        Ext.flatten = ExtArray.flatten;
        Ext.clean = ExtArray.clean;
        Ext.unique = ExtArray.unique;
        Ext.pluck = ExtArray.pluck;
        
        Ext.toArray = function(){
            return ExtArray.toArray.apply(ExtArray,arguments);    
        }
        
    })();
  • 相关阅读:
    [js]vue-router的使用
    [js]递归实现 数组转树形
    [js]vue组件核心
    [js]了解chart绘图
    [js]vue权限控制
    [js]vue显示一个外部链接的组件
    [js]axios使用
    [js]vue中 给router-view 组件的 绑定 key 的原因
    [java]BeanPostProcessor使用及源码
    [java]权限管理
  • 原文地址:https://www.cnblogs.com/wangjuneng/p/4474794.html
Copyright © 2011-2022 走看看