JavaScript Array 对象与排序

API:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

javaScript的Array对象是用于构造数组的全局对象,数组类似于列表的高阶对象。在javaScript的数组中,元素没有任何限制 , 可以保存所有类型,如:
var a = [
  'test',
  123,
  false,
  [1,3,3],
  {id: 1, value: 3},
  null,
  undefined
]

创建数组:
方式一:使用new操作符
   var arr = new Array(5);
   //指定数组长度,但打印数组时,每一位上都是undefined
   //注意是使用new Array时,若只有一个参数时表示的是数组的长度

var arr = new Array(5,3); //数组里保存了两个元素 5 和 3

 

方式二:
var arr = [1,2,3];//这种方式更为常见

 

数组的长度,Array.length

 
在普通编程语言当中(如:java),数组长度是不可变的,而在JS当中,数组长度是可变的,删除元素,添加元素,不需要关心长度,它会自动变化。这种特性产生了对数组长度的一些用法,如:
// 清空数组 
arr.length = 0 
// 截取数组前n个元素
arr.length = n

 

数组为什么是object类型?
JS是面相对象的语言,JS数组的本质,就是对象。   对象的本质,是哈希。   哈希的本质是数组
 //原理: 在JS中,数组实际上是一个做了特殊处理的对象
var obj = {
    "0" : 1,
    "1" : 2,
    "2" : 3,
    "3" : 4,
    "length" : 4
}

 那么我们同样可以使用循环进行遍历

for(var i=0; i<obj.length; i++) {
    console.log(obj[i]);
}

 简单的说,引用类型,即传入的参数是对象就放在堆里(栈里放的是堆的指针);数值类型,不是对象就放在栈里

 
 
数组的默认排序,sort方法(说明   http://www.w3school.com.cn/jsref/jsref_sort.asp)

如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。

如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:

  • 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
  • 若 a 等于 b,则返回 0。
  • 若 a 大于 b,则返回一个大于 0 的值。
/*按照对象的年龄从大到小进行排序*/
function Man(name,age){
    this.name=name;
    this.age=age;
}
var mans=[];
mans.push(new Man("小明",14));
mans.push(new Man("小红",28));
mans.push(new Man("小刚",19));

mans.sort(function(a,b){
    return b.age-a.age;
});
console.log(mans);

 

打乱原有数组

 

var list = [1, 2, 3, 63, 85, 24, 87, 95, 43]
var newList = list.sort( () => Math.random() - 0.5);

 

如何判断某变量是否为数组数据类型?

方法一.判断其是否具有“数组性质”,如push()方法。由于自己也可以给该变量定义push方法,所以这种方式并不准确 

方法二.obj instanceof Array在某些IE版本中不正确

方法三.方法一二皆有漏洞,在ECMA Script5中定义了新方法Array.isArray(),保证其兼容性,最好的方法如下:

if(typeofArray.isArray==="undefined"){
     Array.isArray = function(arg){
         return Object.prototype.toString.call(arg)==="[object Array]"
     }
 }

 

冒泡排序算法

            function select(arr){//冒泡排序
                for(var i=0;i<arr.length-1;i++){
                    for(var j=0;j<arr.length-i;j++){
                        if(arr[j]>arr[j+1]){
                            var t=arr[j];
                            arr[j]=arr[j+1];
                            arr[j+1]=t;
                        
                        }
                    
                    }
                    console.log(arr);
                
                }
                    
            
            }
            select([12,9,38,44,98,7,35,59,49,88,38]);
View Code
选择排序算法
            function select(arr){//选择排序
            
                for(var i=0;i<arr.length-1;i++){
                    for(var j=i+1;j<arr.length;j++){
                            if(arr[i]>arr[j]){
                                var t=arr[i];
                                arr[i]=arr[j];
                                arr[j]=t;
                            }
                        }
                    console.log(arr);
                
                }
                    
                
            }
            select([12,9,38,44,98,7,35,59,49,88,38]);
View Code
快速排序法

            function quick_sort(arr){//快速排序
                if(arr.length<=1)return arr;//当传入的数组长度为1或0时跳出
                var midIndex=parseInt(arr.length/2);//中间值索引
                var midValue=arr[midIndex];//中间值
                var left=[];//比中间值小的放左边
                var right=[];//比中间值大或等于的放右边
                for(var i in arr){
                    if(i==midIndex)continue;//跳过中间值
                    arr[i]<midValue?left.push(arr[i]):right.push(arr[i]);
                }
                return quick_sort(left).concat(midValue,quick_sort(right));//返回结果
                
            
            }
            console.log(quick_sort([12,9,38,44,98,7,35,59,49,88,38]));
View Code

取末尾值作为基准

function quickSort (arr) {
    let len = arr.length;
    if (len <= 1) {
        return arr;
    }
    let value = arr[len -1]; // 获取最后一位数
    let left = [], right = []; 
    for (let i = 0; i < len - 1; i++) {
        let tmp = arr[i];
        value > tmp ? left.push(tmp) : right.push(tmp);
    }
    return quickSort(left).concat(value, quickSort(right));
}
View Code

索引法

function quickSort (arr) {
    function swap (a, i, j) {
        let tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
    function sort (a, i, j) {
        if (i >= j) {
            return;
        }
        let beg = i;
        let end = j;
        while (i + 1 <= j) {
            if (a[i] > a[i + 1]) {
                swap(a, i, i + 1);
                i ++;
            } else {
                swap(a, i + 1, j);
                j --;
            }
        }
        sort(a, beg, i - 1);
        sort(a, j + 1, end);
    }
    sort(arr, 0, arr.length - 1);
    return arr;
}
View Code

 

插入排序

当前元素的前面如果已经没有元素,则无需插入。


如果要插入的元素 < 前一个元素,则进行交换。




依次类推
var list =[12,9,38,44,98,7,35,59,49,88,38];
function insertSort(arr){
    for(var i=0; i<arr.length; i++){
        var n = i;
        while( arr[n] < arr[n-1] && n-1>=0 ){
            var temp = arr[n];
            arr[n] = arr[n-1];
            arr[n-1] = temp;
            n--;
        }
    }
    return arr;
}
View Code
            function insert_sort(arr){//插入排序
                
                for(var i=0;i<arr.length;i++){
                    for(var j=i;j>0;j--){
                        if(arr[j]<arr[j-1]){
                            var tmp=arr[j];
                            arr[j]=arr[j-1];
                            arr[j-1]=tmp;
                        }else{
                            break;
                        }
                        
                    }
                    console.log(arr);
                    
                }
            
            }
            console.log(insert_sort([12,9,38,44,98,7,35,59,49,88,38]));
View Code

 

希尔排序


var list =[12,9,38,44,98,7,35,59,49,88,38];
function shell(arr){
        var interval = parseInt(arr.length/2); //定义一个间隔
        while(interval>=1){
                console.log("间隔"+interval);
                for(var i=0; i<arr.length; i++){               
                        //插入排序
                        var index = i;
                        while(arr[index] < arr[index-interval] && index-interval>=0){ //按照间隔做插入排序
                                //交换
                                [arr[index], arr[index-interval]] = [arr[index-interval], arr[index]];
                                index -= interval;
                        }
                }
                console.log("结果: "+arr);
                interval = parseInt(interval/2);
        }
        return arr;
}

 

            function shell_sort(arr){//希尔排序
                
                for(var j=parseInt(arr.length/2);j>=1;j=parseInt(j/2)){//j为步长,一般来说步长的确定没有严格的要求,但必须有为1的步长
                    for(var i=j;i<arr.length;i++){// 遍历数组
                        
                        for(var k=i;k>0;k-=j){//对间隔为步长的元素进行插入排序
                            if(arr[k]<arr[k-j]){
                                var tmp=arr[k];
                                arr[k]=arr[k-j];
                                arr[k-j]=tmp;
                                console.log(arr);
                            }else{
                                break;
                            }
    
                        }
                    }

                }
            }
            console.log(shell_sort([12,9,38,44,98,7,35,59,49,88,38]));

 

引用传递

var a = [1,2,3];
function add(arr){
    arr[0]++;
}
add(a);

console.log(a);  // [2,2,3]


伪数组如何转换为数组? (http://www.cnblogs.com/NTWang/p/6280447.html)
伪数组举例:
var list = document.getElementsByTagName("p");  

var test = function(){
  console.log(argument); // arguments就是伪数组
}
将伪数组转化为数组对象:
方法一、
        var list = document.getElementsByTagName("p"); 
        
        function toArray(list){ //遍历伪数组,返回新数组
            var newList = [];
             for (var i = 0; i < list.length; i++) {
                 newList.push(list[i]);
             }
             return newList;
        }
        
        console.log(toArray(list));
方法二、使用数组的slice()方法,使用call或者apply指向伪数组
        var list = document.getElementsByTagName("p"); 
        
        var newList = Array.prototype.slice.call(list);
        
        console.log(newList);

ps:slice函数 从某个已有的数组返回选定的元素 http://www.w3school.com.cn/jsref/jsref_slice_array.asp

        Array.prototype.slice = function(start,end){//模拟实现slice
            var result = [];
            var start = start || 0;
            //this指向调用的对象,可使用call或apply重定向
            var end = end || this.length;
            for(var i=0; i < end; i++){
                result.push(this[i]);
            }
            return result;
        
        }

方法三、原型继承

        var list = document.getElementsByTagName("p"); 
        
        list.__proto__ = Array.prototype;
        
        console.log(list instanceof Array);
 方法四、ES6中数组的新方法 Array.from()
        var list = document.getElementsByTagName("p"); 
        
        console.log(Array.from(list) instanceof Array);    



call方法
在JS里面,所有的函数,都属于对象
arr.slice();
function test(){

}
window.test();
既可以
对象.函数名()
也可以
函数.调用(对象);  //JAVA反射机制

举例:
window.test();
test.call(window);


var arr = { };
arr.test(); // 错误!!!

test.call(arr); //正确!
等价于
arr.test();


list.slice();  //错误!

var newlist = [].slice.call(list); //等价于 list.slice()


数组去重
1. ES6 方法,扩展运算符和 Set 结构相结合
let arr = [3, 5, 2, 2, 5, 5];
let unique = [...new Set(arr)]; // [3, 5, 2]

function dedupe(array) {
  return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]); // [1, 2, 3]

 2.在Array对象原型上扩充一个方法unique,实现数组去重

    Array.prototype.unique = function(){
        var result = [],hash = {};
        this.forEach(function(v){
            var type = typeof(v); //获取元素类型
            hash[v] || (hash[v] = new Array());
            if(hash[v].indexOf(type) < 0){
                hash[v].push(type); //存储类型
                result.push(v);
            }
        });
        return result;
    }
 







































 

posted @ 2017-10-27 08:46  fanlinqiang  阅读(346)  评论(0编辑  收藏  举报