如何从数组arr中随机获取n个数据的,返回新数组

背景:最近在仿写qq音乐小程序的时候遇到了这样一个需求:获取到一个接口中的数据是一个列表,列表中有二三十条数据,然而界面中只显示8条。并且根据观察,显示的数据应该是随机的。这时候我就想着封装一个方法解决这样的一个需求。

第一种情况:随机获取的数据不能重复

这种情况只能根据其内容来判断,因为内容不能重复。

function getRandomData(arr, n) {
    let newArr = [],
        len = arr.length;

    while(newArr.length <= 4) {
        //标志位
        let flag = true;

        //随机下标
        let randomIndex = parseInt(Math.random() * len);

        for(let j = 0; j < newArr.length; j++) {
            if(arr[randomIndex] == newArr[j]) {
                flag = false;
                break;
            }

        }
        if(!flag) {
            continue;
        }

        newArr.push(arr[randomIndex]);

        if(newArr.length >= n) {
            break;
        }
    }

    return newArr;
}

console.log(getRandomData([1, 2, 3, 5, 4, 3, 6, 6], 4));

第二种情况: 下标不能重复,即可以出现相同的数据(如果有的话)

这种情况要将前一次循环的下标保存到一个数组,在下一次循环的时候在遍历该数组,一旦发现相同的则跳过该循环。

function getRandomData(arr, n) {
    let newArr = [],
        indexArr = [],
        len = arr.length;

    while(newArr.length <= 4) {
        //标志位
        let flag = true;

        //随机下标
        let randomIndex = parseInt(Math.random() * len);

        for(let j = 0; j < indexArr.length; j++) {
            if(randomIndex == indexArr[j]) {
                flag = false;
                break;
            }

        }
        if(!flag) {
            continue;
        }

        indexArr.push(randomIndex);

        newArr.push(arr[randomIndex]);

        if(newArr.length >= n) {
            break;
        }
    }

    return newArr;
}

console.log(getRandomData([1, 2, 3, 5, 4, 3, 6, 6], 4));

其实,这两种方法在我的项目中结果都一样,因为数据根本不会重复。但严格来说,还是第二种方法比较合适。