[转] 数组常用JS方法(去重、数组抽取随机值)

原文地址

前言

因为平时在写代码的过程中,有些算法会经常重复写,比如数组去重、数组抽取随机值等!虽然这些不是很难的逻辑,但是每次刚开始遇到需求的时候,还是需要琢磨一些时间才能想出来,所以此文档把这些常见算法的思想记录下来,以便下次再遇到的时候不会手脚无措了!
这篇文档不考虑es6等语法,也不考虑Array自带的一些过滤方法!
我们这里不考虑数组上的一个自带的过滤算法,比如map、filter等方法!数组去重的关键是需要一个中间数组来存数组来帮助实现数组去重!

数组去重

方法一:

    var arr = [1,2,3,1,1,1,1];
    function toHeavy(array){
        //这是一个缓存对象,用来实现过滤到重复的数据
        var cache = {};
        //定义一个中间数组,用来实现当容器
        var cacheArr = [];
        for(var i = 0,len = array.length;i<len;i++){
            if(!cache[array[i]]){
                cacheArr.push(array[i]);
                cache[array[i]] = array[i];
            };
        };
        return cacheArr;
    };
    arr = toHeavy(arr);//arr ==  [1,2,3]

方法二:

    var arr = [1,2,3,1,1,1,1,1,1];
    function toHeavy(array){
        var cache = [];
        for(var i = 0,len = array.length;i<len;i++){
            //用闭包,防止isHeavy向外部暴露,当然如果用es6的话,可以用let对isHeavy进行声明也能达到同样的目的
            //因为js中没有块级作用域
            (function(){
                var isHeavy = false;
                for(var j = 0,_len = cache.length;j<_len;j++){
                    if(cache[j] == array[i]){
                        isHeavy = true;
                        break;
                    };
                };
                if(!isHeavy){
                    //如果不是重复的,那么就执行把当前值推送的cache里面
                    cache.push(array[i]);
                };
            })();
        };
        return cache;
    };

    arr = toHeavy(arr);

最后说一句,现实中的数据肯定不会这么简单,可能会是一个稍微复杂的数据,要给这些数组去重你也不要被吓住,其实原理是一样的,只是你被迷惑了而已!

在一个数组中随机抽取一部分值

这个算法的关键要使用Math.random,不说了直接上代码:

    var arr = ['小明','小红','小陈','小于','小兰','小法','小p','小张','小镇','小王','傻逼','怂逼'];

    function getArr(num,array){
        //num表示要去多少个,它不能大于要取的那个数组的最大长度,如果超过了那么就等于它的长度
        var aLength = array.length;
        if(num>=aLength){
            num = aLength;
        };
        var cacheArr = [];
        //我们用一个数组保存原来的数组
        //记住千万能直接赋值,因为数组是一个引用,这样不能保持原来的数组
        //这里也可以用originArr = array.slice()
        // var originArr = (function(){
        //  var arr = [];
        //  for(var i = 0,len = array.length;i<len;i++){
        //      arr.push(array[i]);
        //  };
        //  return arr;
        // })();


        //更新一种获取更简单、更快捷的获取原始数组的方法
        var originArr = array.slice(0);
        for(var i = 0;i<num;i++){
            //array.length不能写成上面的aLength,因为aLength是固定的值,而array.length随着array的改变是自动更新的
            //Math.random() * array.length得到的是一个介于长度和零之间的一个值,包括0但不包含长度值
            //我们算出的是一个浮点值,所以我们必须把它转化成整数
            //因为不能超过最大长度值,所以应该向下取整

            /*更新bug:我们不能在array上操作了,因为这会影响原来的数组,
            所以把这里的array换成originArr
            */
            var _index = Math.floor(Math.random() * originArr.length);
            cacheArr.push(originArr[_index]);
            //记住一定,取出来之后,一定删除原来位置上的数组值
            //要不然数组更新不了
            originArr.splice(_index,1);
        };
        return cacheArr;
    };
    var brr = getArr(5,arr);
    console.log(brr);
    console.log(arr);

得到某个区间的字母组成的数组

这里主要应用两个方法,一个字符串的charCodeAt和String上的一个静态方法fromCharCode。其思想主要是:先得到这个区间开头字母和结束字母的数字表示,然后就可以在这个区间内做一个循环,并且得到这个区间字母的数字表示,最后把数字传唤成字母依次push到数组里面返回。直接上代码:

    function getArrForAlphabet(startLetter,endLetter){
        //var regExp = /^[a-zA-Z]$/gi;
        var regExp = new RegExp("^[a-zA-Z]$");
        if(!regExp.test(startLetter) || !regExp.test(endLetter)){
            //console.log(regExp.test(startLetter));
            //console.log(regExp.test(endLetter));
            console.log('请传入字母!');
            return false;
        };
        //i是得到开始字母的数字表示,j得到结束字母的数字表示
        var i = startLetter.charCodeAt(0),j = endLetter.charCodeAt(0);
        //定义一个数组用于取出将来的字母
        var arr = [];
        //这里取<=符号是因为要取出结束的字母
        for(;i<=j;i++){ 
            //fromCharCode是String上的一个静态方法,用于将一个数字转换成对应的字母
            var letter = String.fromCharCode(i);
            arr.push(letter);
        };
        //记得最后返回arr
        return arr;
    };
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容