怎样随机&&去重返回新数组

1.题目原由

W姐毫无征象的在我们的水群里发来一段代码:

var arr = [{q:"1+1=?",a:"2",b:"3",c:"1"},{q:"1+2=?",a:"2",b:"3",c:"7"},{q:"1+0=?",a:"8",b:"3",c:"1"},{q:"1+7=?",a:"8",b:"3",c:"7"},{q:"2+2=?",a:"4",b:"7",c:"1"},{q:"1+3=?",a:"2",b:"4",c:"6"},{q:"1+70=?",a:"72",b:"73",c:"71"},{q:"1+18=?",a:"22",b:"19",c:"21"},{q:"7+11=?",a:"18",b:"23",c:"21"}];
  var resArr = [];
  for(var i = 0; i<5; i++){
    var index = parseInt(Math.random()*10);
    resArr.push(arr[index]);
    for( var j = 0; j<resArr.length; j++){
      if(resArr[j] == resArr[j+1]){
        resArr.shift();
        --i;
      }
    }
  }
  console.log(resArr);

她的目标是想从arr中随机抽取5个不反复的值构成一个新数组resArr.问我代码是不是有题目,很遗憾由于我刚睡醒,随意贴了一下代码,运行了一下就说没题目…很快我就被打脸了(也是,假如没题目标话她问个毛..).
人人能够先找一下题目,下面先改正这段代码,然后再给出群里剩下两位老大的解决要领.

2.代码改正

起首先贴出改正后的代码:

 for(var i = 0; i<5; i++){
        var index = parseInt(Math.random()*arr.length);//限定局限
            resArr.push(arr[index]);
        //每次只需要末了一个压入数组的元素resArr[i]与之前一切元素举行比较
        //若碰到反复的,将resArr[i]弹出并停止轮回即可
        for( var j = 0; j<resArr.length-1; j++){
            if(resArr[i]== resArr[j]){
                resArr.pop();
                --i;
                break
            }
        }
    }
    console.log(resArr);

错的缘由就是解释里的,我竟然一眼没看出来,真是深感忸捏…看来不能眼高手低,很多敲代码了.

3.别的解决要领

我们4人水群里me和别的两位也给出了差异的思绪.

3.1水货me给出的思绪

作为小水货的我,当时没有马上看出来毛病的处所,所以直接又写了一个水水的要领,请人人不要见笑….

function solve(arr,num){
    var resArr=[],indexArr=[];
    for (var j = 0; j < arr.length; j++) {
        indexArr[j] = 0;
    }
    for(var i=0;i<num;){
        var index = parseInt(Math.random() * arr.length);
        if (!indexArr[index]&& arr[index]) {
            indexArr[index] = 1
            resArr.push(arr[index]);
            i++;
        }
    }
    return resArr;
}
console.log(solve(arr,5))

这里重要运用一个数组indexArr作为一个表纪录已被挑选过值,若涌现反复则直接跳过.

3.2YC大神给出的解决要领

YC大神作为我们中薪水最高,加班时刻最长的,百忙中抽出时刻给出了本身的解决计划,在此替W姐感谢过劳肥的YC大神.

function filter(arr, num) {
        var newArr = [];
        //随机删并返回一个值,由于原数组举行了删除操纵,就防止了查重
        var pick = function () {
            var index = Math.ceil((arr.length * Math.random())) - 1;
            return arr.splice(index, 1);
        }
        for (var i = 0; i < num; i++) {
           // newArr.push(pick()[0])//如许写就不必数组扁平化了
            newArr.push(pick());
        }
        return newArr
    }
    //数组扁平化
    function flatten(arr) {
        return arr.reduce(function (prev, item) {
            return prev.concat(Array.isArray(item) ? flatten(item) : item);
        }, []);
    }
    var b=flatten(filter(arr, 5))
    console.log(b)

由于一开始看到返回值的时刻就想到一个叫做数组扁平化的东西,很凄惨的是只记得名字忘记了完成计划,所以趁此温习一下.这个计划不好的一点就是修正了原数组,如许就无发复用该数组,解决要领是能够在函数中举行一个深拷贝,运用新数组举行操纵防止修正原数组.

3.3joker老大的解决计划

joker老大作为我们中身体和脸最好的,以自满的姿势给出了我们几个公认最优的解决计划.

//中心是随机排序,对传入的o举行o.length次的随机交流,并运用slice举行截取返回
var shuffle = function (o, num) { 
        for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x) ;
        return o.slice(0, 5);
    };
    console.log(shuffle(arr))

slice()要领返回原数组的一个浅复制,不修正原数组内容.而且效力也高,只用到了一个for轮回,假如说有缺点的话就是可读性略差一些,下面睁开一下:

 var newShuffle=function(o,num){
        var j,tmp,i=o.length;
        while(i){
            j=parseInt(Math.random() * i);
            tmp=o[--i];
            o[i]=o[j];
            o[j]=tmp;
            
        }
        return o.slice(0,num)
    }
  console.log(newShuffle(arr,5))

4假如人人发明和我内容差异不大的博客内容

谁人就是w姐的博客..欺侮我打字慢..
《怎样随机&&去重返回新数组》

W姐的博客地址

    原文作者:梦中的贝壳
    原文地址: https://segmentfault.com/a/1190000014048072
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞