복붙노트

[JQUERY] 어떻게 배열에서 임의의 요소의 수를 얻으려면?

JQUERY

어떻게 배열에서 임의의 요소의 수를 얻으려면?

해결법


  1. 1.이 비파괴 (빠른) 함수를보십시오 :

    이 비파괴 (빠른) 함수를보십시오 :

    function getRandom(arr, n) {
        var result = new Array(n),
            len = arr.length,
            taken = new Array(len);
        if (n > len)
            throw new RangeError("getRandom: more elements taken than available");
        while (n--) {
            var x = Math.floor(Math.random() * len);
            result[n] = arr[x in taken ? taken[x] : x];
            taken[x] = --len in taken ? taken[len] : len;
        }
        return result;
    }
    

  2. 2.그냥 두 줄 :

    그냥 두 줄 :

    // Shuffle array
    const shuffled = array.sort(() => 0.5 - Math.random());
    
    // Get sub-array of first n elements after shuffled
    let selected = shuffled.slice(0, n);
    

  3. 3.여기에 한 줄 유일한 해결책은있다

    여기에 한 줄 유일한 해결책은있다

     array.sort(() => Math.random() - Math.random()).slice(0, n)
    

  4. 4.파이썬 표준 라이브러리에서 .sample 이식 :

    파이썬 표준 라이브러리에서 .sample 이식 :

    function sample(population, k){
        /*
            Chooses k unique random elements from a population sequence or set.
    
            Returns a new list containing elements from the population while
            leaving the original population unchanged.  The resulting list is
            in selection order so that all sub-slices will also be valid random
            samples.  This allows raffle winners (the sample) to be partitioned
            into grand prize and second place winners (the subslices).
    
            Members of the population need not be hashable or unique.  If the
            population contains repeats, then each occurrence is a possible
            selection in the sample.
    
            To choose a sample in a range of integers, use range as an argument.
            This is especially fast and space efficient for sampling from a
            large population:   sample(range(10000000), 60)
    
            Sampling without replacement entails tracking either potential
            selections (the pool) in a list or previous selections in a set.
    
            When the number of selections is small compared to the
            population, then tracking selections is efficient, requiring
            only a small set and an occasional reselection.  For
            a larger number of selections, the pool tracking method is
            preferred since the list takes less space than the
            set and it doesn't suffer from frequent reselections.
        */
    
        if(!Array.isArray(population))
            throw new TypeError("Population must be an array.");
        var n = population.length;
        if(k < 0 || k > n)
            throw new RangeError("Sample larger than population or is negative");
    
        var result = new Array(k);
        var setsize = 21;   // size of a small set minus size of an empty list
    
        if(k > 5)
            setsize += Math.pow(4, Math.ceil(Math.log(k * 3, 4)))
    
        if(n <= setsize){
            // An n-length list is smaller than a k-length set
            var pool = population.slice();
            for(var i = 0; i < k; i++){          // invariant:  non-selected at [0,n-i)
                var j = Math.random() * (n - i) | 0;
                result[i] = pool[j];
                pool[j] = pool[n - i - 1];       // move non-selected item into vacancy
            }
        }else{
            var selected = new Set();
            for(var i = 0; i < k; i++){
                var j = Math.random() * n | 0;
                while(selected.has(j)){
                    j = Math.random() * n | 0;
                }
                selected.add(j);
                result[i] = population[j];
            }
        }
    
        return result;
    }
    

    구현 lib 디렉토리 / random.py에서 포팅.

    메모:

    허용 대답에 대한 성능 :


  5. 5.원래 배열을 변경하지 않고 5 개 무작위로 아이템을 얻기 :

    원래 배열을 변경하지 않고 5 개 무작위로 아이템을 얻기 :

    const n = 5;
    const sample = items
      .map(x => ({ x, r: Math.random() }))
      .sort((a, b) => a.r - b.r)
      .map(a => a.x)
      .slice(0, n);
    

    (큰 목록이 사용하지 마십시오)


  6. 6.것을 수행하는 함수를 만들 :

    것을 수행하는 함수를 만들 :

    var getMeRandomElements = function(sourceArray, neededElements) {
        var result = [];
        for (var i = 0; i < neededElements; i++) {
            result.push(sourceArray[Math.floor(Math.random()*sourceArray.length)]);
        }
        return result;
    }
    

    sourceArray 반환 할 수있는 충분한 요소를 가지고 있다면 당신은 또한 확인해야합니다. 당신이 원하는 경우 유일한 요소는 당신이 sourceArray에서 선택된 요소를 제거해야합니다 반환.


  7. 7.ES6 구문

    ES6 구문

    const pickRandom = (arr,count) => {
      let _arr = [...arr];
      return[...Array(count)].map( ()=> _arr.splice(Math.floor(Math.random() * _arr.length), 1)[0] ); 
    }
    

  8. 8.당신이 무작위로 반복없이 루프에서 배열에서 항목을 얻고 싶은 경우에 당신은 스플 ​​라이스와 배열에서 선택한 항목을 제거 할 수 있습니다 :

    당신이 무작위로 반복없이 루프에서 배열에서 항목을 얻고 싶은 경우에 당신은 스플 ​​라이스와 배열에서 선택한 항목을 제거 할 수 있습니다 :

    VAR 항목 = [1, 2, 3, 4, 5]; VAR의 newItems = []; 위한 VAR (I = 0; I <3; I ++) { VAR IDX = Math.floor (인 Math.random () * items.length); newItems.push (항목 [IDX]); items.splice (IDX, 1); } CONSOLE.LOG (newItems);


  9. 9.

    Array.prototype.getnkill = function() {
        var a = Math.floor(Math.random()*this.length);
        var dead = this[a];
        this.splice(a,1);
        return dead;
    }
    
    //.getnkill() removes element in the array 
    //so if you like you can keep a copy of the array first:
    
    //var original= items.slice(0); 
    
    
    var item = items.getnkill();
    
    var anotheritem = items.getnkill();
    

  10. 10.여기에 멋지게 입력 한 버전이다. 그것은 실패하지 않습니다. 반환 샘플 크기가 원래 배열의 길이보다 큰 경우에 단행 배열입니다.

    여기에 멋지게 입력 한 버전이다. 그것은 실패하지 않습니다. 반환 샘플 크기가 원래 배열의 길이보다 큰 경우에 단행 배열입니다.

    function sampleArr<T>(arr: T[], size: number): T[] {
      const setOfIndexes = new Set<number>();
      while (setOfIndexes.size < size && setOfIndexes.size < arr.length) {
        setOfIndexes.add(randomIntFromInterval(0, arr.length - 1));
      }
      return Array.from(setOfIndexes.values()).map(i => arr[i]);
    }
    
    const randomIntFromInterval = (min: number, max: number): number =>
      Math.floor(Math.random() * (max - min + 1) + min);
    

  11. 11.편집 :이 솔루션은 당신은 단지 몇 가지 요소를 얻으려면 (소스 배열을 스플 라이스) 여기에 제시된 다른 사람보다 느립니다. 플라이 싱 용액의 속도가 출력 배열에 필요한 소자의 수에 의존하면서 용액의 속도는 단지 원래 배열의 요소의 수에 따라 달라진다.

    편집 :이 솔루션은 당신은 단지 몇 가지 요소를 얻으려면 (소스 배열을 스플 라이스) 여기에 제시된 다른 사람보다 느립니다. 플라이 싱 용액의 속도가 출력 배열에 필요한 소자의 수에 의존하면서 용액의 속도는 단지 원래 배열의 요소의 수에 따라 달라진다.

    당신이 임의 요소를-반복이 아닌 싶은 경우에, 당신은 당신이 원하는대로 많은로만 얻을 배열 셔플 수 있습니다 :

    function shuffle(array) {
        var counter = array.length, temp, index;
    
        // While there are elements in the array
        while (counter--) {
            // Pick a random index
            index = (Math.random() * counter) | 0;
    
            // And swap the last element with it
            temp = array[counter];
            array[counter] = array[index];
            array[index] = temp;
        }
    
        return array;
    }
    
    var arr = [0,1,2,3,4,5,7,8,9];
    
    var randoms = shuffle(arr.slice(0)); // array is cloned so it won't be destroyed
    randoms.length = 4; // get 4 random elements
    

    DEMO : http://jsbin.com/UHUHuqi/1/edit

    여기에서 가져온 셔플 기능 : https://stackoverflow.com/a/6274398/1669279


  12. 12.나는 여기를 공유하고 있습니다 때문에 문제의이 종류를 해결하기 위해 기능을 필요로했다.

    나는 여기를 공유하고 있습니다 때문에 문제의이 종류를 해결하기 위해 기능을 필요로했다.

        const getRandomItem = function(arr) {
            return arr[Math.floor(Math.random() * arr.length)];
        }
    
        // original array
        let arr = [4, 3, 1, 6, 9, 8, 5];
    
        // number of random elements to get from arr
        let n = 4;
    
        let count = 0;
        // new array to push random item in
        let randomItems = []
        do {
            let item = getRandomItem(arr);
            randomItems.push(item);
            // update the original array and remove the recently pushed item
            arr.splice(arr.indexOf(item), 1);
            count++;
        } while(count < n);
    
        console.log(randomItems);
        console.log(arr);
    

    참고 : = 기본적으로 당신이 배열을 단행 배열 편곡 및 randomItems 반환 셔플하고 다음 arr.length N합니다.

    데모


  13. 13.이 응답에서는, 나는 당신과 내가 모든 요소가 임의의 부분 배열을위한 동등한 기회를 제공하는 가장 좋은 방법을 알고 있는지 테스트를 공유하고자합니다.

    이 응답에서는, 나는 당신과 내가 모든 요소가 임의의 부분 배열을위한 동등한 기회를 제공하는 가장 좋은 방법을 알고 있는지 테스트를 공유하고자합니다.

    array.sort(() => Math.random() - Math.random()).slice(0, n)
    

    이 방법을 사용하여, 일부 요소는 다른 사람과 비교하여 더 높은 가능성을 가지고있다.

    calculateProbability = 함수 (번호 = 0, 반복 = 10000 arraySize = 100) { 하자 OCC = 0 {(++ 인덱스; 색인 <반복 인덱스 = 0을하자)에 대한 CONST에서 myArray = Array.from (배열 (arraySize) .keys ()) // => [0, 1, 2, 3, 4, ... arraySize] / ** 잘못된 방법 * / CONST 도착 myArray.sort = (함수 () { 반환 발 = 0.5 - 인 Math.random (); }); 경우 (도착 [0] === 번호) { OCC ++ } } CONSOLE.LOG ( "확률", 숫자 "=", OCC * 100 / 반복 "%") } calculateProbability (0) calculateProbability (0) calculateProbability (0) calculateProbability (50) calculateProbability (50) calculateProbability (50) calculateProbability (25) calculateProbability (25) calculateProbability (25)

    이 방법을 사용하여, 요소가 동일한 확률을 가지고

     const arr = myArray
          .map((a) => ({sort: Math.random(), value: a}))
          .sort((a, b) => a.sort - b.sort)
          .map((a) => a.value)
    

    calculateProbability = 함수 (번호 = 0, 반복 = 10000 arraySize = 100) { 하자 OCC = 0 {(++ 인덱스; 색인 <반복 인덱스 = 0을하자)에 대한 CONST에서 myArray = Array.from (배열 (arraySize) .keys ()) // => [0, 1, 2, 3, 4, ... arraySize] / ** 올바른 방법 * / CONST = myArray의 도착 .MAP ((a) => ({분류 : 인 Math.random ()를 값 : A})) .sort ((a, b) => a.sort - b.sort) .MAP ((a) => a.value) 경우 (도착 [0] === 번호) { OCC ++ } } CONSOLE.LOG ( "확률", 숫자 "=", OCC * 100 / 반복 "%") } calculateProbability (0) calculateProbability (0) calculateProbability (0) calculateProbability (50) calculateProbability (50) calculateProbability (50) calculateProbability (25) calculateProbability (25) calculateProbability (25)

    정답은 다음 링크에 게시됩니다 : https://stackoverflow.com/a/46545530/3811640


  14. 14.여기에 코드의 최적화 된 버전이 가장 빠른 알고리즘이 함께 갈 수 있다면 만드는 추가 파괴 (현재 위치에서) 옵션과 함께 @Derek 파이썬에서 포팅입니다. 그렇지 않으면 어느 완전한 복사본을 만들거나, 큰 배열로부터 요청 적은 수의 항목에 대해, 선택 알고리즘을 기반으로 전환한다.

    여기에 코드의 최적화 된 버전이 가장 빠른 알고리즘이 함께 갈 수 있다면 만드는 추가 파괴 (현재 위치에서) 옵션과 함께 @Derek 파이썬에서 포팅입니다. 그렇지 않으면 어느 완전한 복사본을 만들거나, 큰 배열로부터 요청 적은 수의 항목에 대해, 선택 알고리즘을 기반으로 전환한다.

    // Chooses k unique random elements from pool.
    function sample(pool, k, destructive) {
        var n = pool.length;
    
        if (k < 0 || k > n)
            throw new RangeError("Sample larger than population or is negative");
    
        if (destructive || n <= (k <= 5 ? 21 : 21 + Math.pow(4, Math.ceil(Math.log(k*3, 4))))) {
            if (!destructive)
                pool = Array.prototype.slice.call(pool);
            for (var i = 0; i < k; i++) { // invariant: non-selected at [i,n)
                var j = i + Math.random() * (n - i) | 0;
                var x = pool[i];
                pool[i] = pool[j];
                pool[j] = x;
            }
            pool.length = k; // truncate
            return pool;
        } else {
            var selected = new Set();
            while (selected.add(Math.random() * n | 0).size < k) {}
            return Array.prototype.map.call(selected, i => population[i]);
        }
    }
    

    가장 성능이 좋은 하나 - 지금은 파괴적인 옵션을 가지고 있지만, 조금 느린 크롬하면서 데릭의 구현에 비교하여, 최초의 알고리즘은 파이어 폭스에서 훨씬 빠릅니다. 두 번째 알고리즘 5-15 % 빠른 간단하다. 그들은 K와 N에 따라 달라질 수 있기 때문에 나는 어떤 구체적인 번호를 부여하지 않으려 아마 새 브라우저 버전과 미래에 평균 아무것도하지 않습니다.

    파이썬 코드에서 알고리즘의 유래 사이의 선택을 만드는 발견. 같이 나는 때때로 사람은 느린 선택하지만, 그것을 떠 났어요. 그것은 JS에 최적화 된,하지만 코너 케이스의 성능이 반드시 브라우저이며, 자신의 버전에 의존하기 때문에 그것은 복잡한 작업입니다해야합니다. 1000 또는 1050의 20 아웃을 선택하려고 할 때 예를 들어, 첫 번째 또는 이에 따라 두 번째 알고리즘으로 전환됩니다. 이 경우 첫 번째 실행 빠르게 두 번째 크롬 80에서 하나를 제외한 느린 파이어 폭스 (74)의 3 배 이상 2 배.


  15. 15.lodash (https://lodash.com/) _.sample 및 _.sampleSize.

    lodash (https://lodash.com/) _.sample 및 _.sampleSize.

    컬렉션의 크기까지 컬렉션에서 고유 키 하나 개 또는 N 랜덤 요소를 얻는다.

    _.sample([1, 2, 3, 4]);
    // => 2
    
    _.sampleSize([1, 2, 3], 2);
    // => [3, 1]
     
    _.sampleSize([1, 2, 3], 4);
    // => [2, 3, 1]
    

  16. 16.2,020 불변의 컨텍스트에서 작업 비 파괴 기능 프로그래밍 스타일.

    2,020 불변의 컨텍스트에서 작업 비 파괴 기능 프로그래밍 스타일.

    CONST _randomslice = AR (크기) => { new_ar = ... AR]하자; new_ar.splice (Math.floor (인 Math.random () * ar.length), 1); 리턴 ar.length <= (크기 + 1)? new_ar : _randomslice (new_ar 크기); } CONSOLE.LOG (_randomslice ([1,2,3,4,5], 2));


  17. 17.그것의 충분히 얻을 또는 srcArray에 더 이상의 요소를 추출 남아 있지 동안 그것은 하나 srcArray 하나에서 임의의 요소를 추출합니다. 빠르고 신뢰할 수있는.

    그것의 충분히 얻을 또는 srcArray에 더 이상의 요소를 추출 남아 있지 동안 그것은 하나 srcArray 하나에서 임의의 요소를 추출합니다. 빠르고 신뢰할 수있는.

    함수 getNRandomValuesFromArray (srcArr, N) { // 복사를하는 것은 원래 srcArray에 영향을주지해야 할 일 srcArr srcArr.slice = (); resultArr = []; // srcArray가 비어 있지 않은 우리는 충분히 랜덤 요소가되지 않았지만 반면 (srcArr.length && resultArr.length


  18. 18.2019

    2019

    이 요소가 고유 한 (더 중복)없는 단지, Laurynas Mališauskas 답변과 동일합니다.

    var getMeRandomElements = function(sourceArray, neededElements) {
        var result = [];
        for (var i = 0; i < neededElements; i++) {
        var index = Math.floor(Math.random() * sourceArray.length);
            result.push(sourceArray[index]);
            sourceArray.splice(index, 1);
        }
        return result;
    }
    

    이제 여기에 당신이 가고, "jQuery를 여러 무작위 요소를 얻는 방법"원래의 질문에 대답 :

    var getMeRandomElements = function(sourceArray, neededElements) {
        var result = [];
        for (var i = 0; i < neededElements; i++) {
        var index = Math.floor(Math.random() * sourceArray.length);
            result.push(sourceArray[index]);
            sourceArray.splice(index, 1);
        }
        return result;
    }
    
    var $set = $('.someClass');// <<<<< change this please
    
    var allIndexes = [];
    for(var i = 0; i < $set.length; ++i) {
        allIndexes.push(i);
    }
    
    var totalRandom = 4;// <<<<< change this please
    var randomIndexes = getMeRandomElements(allIndexes, totalRandom);
    
    var $randomElements = null;
    for(var i = 0; i < randomIndexes.length; ++i) {
        var randomIndex = randomIndexes[i];
        if($randomElements === null) {
            $randomElements = $set.eq(randomIndex);
        } else {
            $randomElements.add($set.eq(randomIndex));
        }
    }
    
    // $randomElements is ready
    $randomElements.css('backgroundColor', 'red');
    

  19. 19.여기에 당신이 쉽게 또는 교체하지 않고 배열을 샘플링 할 수있는 기능 I 사용이다 :

    여기에 당신이 쉽게 또는 교체하지 않고 배열을 샘플링 할 수있는 기능 I 사용이다 :

      // Returns a random sample (either with or without replacement) from an array
      const randomSample = (arr, k, withReplacement = false) => {
        let sample;
        if (withReplacement === true) {  // sample with replacement
          sample = Array.from({length: k}, () => arr[Math.floor(Math.random() *  arr.length)]);
        } else { // sample without replacement
          if (k > arr.length) {
            throw new RangeError('Sample size must be less than or equal to array length         when sampling without replacement.')
          }
          sample = arr.map(a => [a, Math.random()]).sort((a, b) => {
            return a[1] < b[1] ? -1 : 1;}).slice(0, k).map(a => a[0]); 
          };
        return sample;
      };
    

    그것을 사용하는 것은 간단하다 :

    교체하지 않고 (기본 동작)

    randomSample ([1, 2, 3, 2)를 호출 할 수있다 [2, 1]

    교체로

    randomSample가 ([1, 2, 3, 4, 5, 6, 4)를 호출 할 수있다 [2, 3, 3, 2]


  20. 20.

    var getRandomElements = function(sourceArray, requiredLength) {
        var result = [];
        while(result.length<requiredLength){
            random = Math.floor(Math.random()*sourceArray.length);
            if(result.indexOf(sourceArray[random])==-1){
                result.push(sourceArray[random]);
            }
        }
        return result;
    }
    

  21. 21.그 어느 것도 꽤 깨끗하고 똑 바른 앞으로이 방법을 언급하지 않았다 믿을 수 없다.

    그 어느 것도 꽤 깨끗하고 똑 바른 앞으로이 방법을 언급하지 않았다 믿을 수 없다.

    const getRnd = (a, n) => new Array(n).fill(null).map(() => a[Math.floor(Math.random() * a.length)]);
    

  22. 22.여기에 가장 정답이고 그것을 당신에게 무작위 + 고유 요소를 제공 할 것입니다.

    여기에 가장 정답이고 그것을 당신에게 무작위 + 고유 요소를 제공 할 것입니다.

    function randomize(array, n)
    {
        var final = [];
        array = array.filter(function(elem, index, self) {
            return index == self.indexOf(elem);
        }).sort(function() { return 0.5 - Math.random() });
    
        var len = array.length,
        n = n > len ? len : n;
    
        for(var i = 0; i < n; i ++)
        {
            final[i] = array[i];
        }
    
        return final;
    }
    
    // randomize([1,2,3,4,5,3,2], 4);
    // Result: [1, 2, 3, 5] // Something like this
    

  23. 23.items.sort (() => (인 Math.random ()> 0.5 내지 1 : 27)?) 슬라이스 (0 카운트).

    items.sort (() => (인 Math.random ()> 0.5 내지 1 : 27)?) 슬라이스 (0 카운트).

  24. from https://stackoverflow.com/questions/19269545/how-to-get-a-number-of-random-elements-from-an-array by cc-by-sa and MIT license