Rastgele değerler içeren bir dizi oluşturun


Yanıtlar:


52

İşte benzersiz sayıların bir listesini karıştıran bir çözüm (asla tekrar yok).

for (var a=[],i=0;i<40;++i) a[i]=i;

// http://stackoverflow.com/questions/962802#962890
function shuffle(array) {
  var tmp, current, top = array.length;
  if(top) while(--top) {
    current = Math.floor(Math.random() * (top + 1));
    tmp = array[current];
    array[current] = array[top];
    array[top] = tmp;
  }
  return array;
}

a = shuffle(a);

Tekrarlanan değerlere izin vermek istiyorsanız (bu, OP'nin istediği şey değildir) o zaman başka yere bakın. :)


4
Bu çözüm, sayıların benzersiz olması gerekiyorsa iyidir, ancak bu tamamen farklı bir istatistiksel / olasılıklı şeydir. Umarım bu OP için açıktı ve onların durumuyla ilgili değildi, ancak bazı durumlarda programın doğruluğu üzerinde büyük bir etkisi olabilir. (Cevabı eleştirmiyorum, sadece gelecekteki okuyucular için bir bayrak kaldırıyorum. Bundan bahsetmek isteyebilirsiniz.) Ayrıca bakınız: en.wikipedia.org/wiki/Combination ("ile" veya "tekrar olmadan" arasındaki ayrım
chiccodoro

var random_array = new Array (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0.5); Bunun yukarıdakiyle aynı şeyi yaptığını düşünüyorum
Jamie337nichols

0 sayısını üretmekten nasıl hariç tutulur?
Gosi

İşte size min / maks esnekliği sağlayan ancak yine de benzersiz sayılar dizisi sağlayan bir ES6 sürümü: pastie.org/p/069IAzSzsRhN6JXdAIpPhc
Curt

219

En kısa yaklaşım (ES6)

// randomly generated N = 40 length array 0 <= A[N] <= 39
Array.from({length: 40}, () => Math.floor(Math.random() * 40));

Zevk almak!


Haklısın. Yorumumu sildim. Gerçek en kısa yolun düzeltilmiş versiyonu: [... Array (20)]. Map (() => {return Math.floor (Math.random () * 30)});
jaheraho

7
Cevabın yaklaşımındaki boşlukları kaldırırsak, önerdiğinizden 4 karakter daha azdır. Tabii ki, golf oynamakla ilgileniyorsanız, aslında bazı kolay karakter kesme kısayollarını atlamışsınızdır: [...Array(40)].map(_=>Math.ceil(Math.random()*40));sizinkinden 11 karakter, orijinalinden 7 karakter daha az olacaktır.
Kyle Baker

(düzeltmek için yeterince hızlı değildi - kullanırsak OP'nin kriterlerini karşılamak için * 39 olması gerekir Math.ceil, ancak bir seçenek olarak 0'ı çıkarırız. 0-39 yerine 1-40'ı kabul edebilirsek, bu işe yarar. Aksi takdirde , geri dönerken iyileştirme karakterini azaltın Math.floor)
Kyle Baker

45

ES5:

function randomArray(length, max) {
    return Array.apply(null, Array(length)).map(function() {
        return Math.round(Math.random() * max);
    });
}

ES6:

randomArray = (length, max) => [...new Array(length)]
    .map(() => Math.round(Math.random() * max));

1
_Ve iargümanlarının nesi var ? ES6'da yanılmıyorsam gereksiz.
AfricanMatt

2
@AfricanMatt, _geçerli öğedir ve geçerli dizindir i. Haklısın, her iki durumda da gereksizler. İsterseniz onları kaldırabilirsiniz.
Eugene Kulabuhov

1
ES6 sürümünün nerede çalıştığına inandığınızı bilmiyorum? Array.from çalışır ... işte kodunuzla bir örnek ... randomArray = (uzunluk: sayı, maks: sayı) => Array.from ({uzunluk}) .map (() => Math.floor (Matematik .random () * maks));
Christian Matthew

34

Daha da kısa ES6 yaklaşımı:

Array(40).fill().map(() => Math.round(Math.random() * 40))

Ayrıca, bağımsız değişkenlere sahip bir işleve sahip olabilirsiniz:

const randomArray = (length, max) => 
  Array(length).fill().map(() => Math.round(Math.random() * max))

1
.fill () bir değer parametresi gerektiriyor
Damian Green

4
@DamianGreen - .fill()herhangi bir parametre olmadan diziyi dolduracak, undefinedburada .map()çalışmak için gereken tek şey bu
vsync

@Damjan sayıları tekrar etmemenin bir yolu var mı? Bu yaklaşımı sevdim
Henrique

@Henrique değişkenleri kullanıyor mu? 🤔
Sebj

@Sebj bu mümkün mü? Demek istediğim, bunun gibi kısa ve uzunluk ve maks. Sahne ile herhangi bir yaklaşım benim için mükemmel çalışır :)
Henrique

32

En kısa :-)

[...Array(40)].map(e=>~~(Math.random()*40))


20
~~Math.floor kelimesinin kısaltmasıdır
Curt

1
bu harika; bu ~~steno için yaygın bir destek var mı? (düzenleme: ahh, bu sadece bitsel bir operatör , görüyorum)
Rafe Goldberg

@Curt sadece pozitif sayılar için
AJ Uppal

1
Ne yazık ki, "sert" bir cevap değil. Gülümseyerek cevap verdi.
OXiGEN

@AJUppal OP, 0-39 arasında belirli bir örnek istedi, bu yüzden öylece gidiyorum
Curt

16

Math.random()0 ile 1 (hariç) arasında bir sayı döndürecektir. Yani, 0-40 istiyorsanız, onu 40 ile çarpabilirsiniz, en yüksek sonuç, ile çarptığınız şey olabilir.

var arr = [];
for (var i=0, t=40; i<t; i++) {
    arr.push(Math.round(Math.random() * t))
}
document.write(arr);

http://jsfiddle.net/robert/tUW89/


1
Açıklığa kavuşturmak için: "l = 40", "i <l" ve "Math.random () * l" de bu bir L harfi, 1 rakamı değil. Yazı tipi anlatmayı zorlaştırıyor.
Mu Mind

11

.. aldığım dizi çok az rastgele. Bir sürü ardışık sayı bloğu üretir ...

Rastgele öğeler dizileri genellikle ardışık sayı blokları içerir, bkz. Kumarbazın Yanılgısı . Örneğin:

.. az önce arka arkaya dört tur attık .. Art arda beş tura çıkma olasılığı yalnızca 1⁄32 olduğundan, kumarbazın yanılgısına maruz kalan bir kişi bu sonraki atmanın tura olma olasılığının daha düşük olduğuna inanabilir. kuyruk olmak. http://en.wikipedia.org/wiki/Gamblers_fallacy


Tam olarak +1. Bir kişinin gerçek (istatistiksel olarak) rastgele sayılara mı yoksa "rastgele görünen" sayılara mı ihtiyaç duyduğuna karar vermesi gerekir.
chiccodoro

5
let randomNumber = Array.from({length: 6}, () => Math.floor(Math.random() * 39));

Görmeyi kolaylaştırmak için diziyi 6 değerle sınırlandırdı.


4

Sayı aralığı kısıtlı olduğundan, yapılacak en iyi şeyin diziyi oluşturmak olduğunu söyleyebilirim, onu sıfırdan 39'a kadar sayılarla (sırayla) doldurun, sonra karıştırın.



Aradaki her sayıyı istediğini bilmiyorum, tamamen rastgele mi? Rastgele sırayla, statik değerlerle iyiyse bu iyi çalışacaktır.
Robert

Bu, işi yapabilir, ancak Math.random()40 kez kullandığınızdan biraz farklı sonuçlar verecektir , çünkü her sayının bir kez görünmesini ve tekrar yapılmamasını sağlar.
Mu Mind

3
var myArray = [];
var arrayMax = 40;
var limit = arrayMax + 1;
for (var i = 0; i < arrayMax; i++) {
  myArray.push(Math.floor(Math.random()*limit));
}

Yukarıdaki, bunu yapmanın geleneksel yoludur, ancak pahalı hesaplamalar yapmak zorunda kalmadan dizinizdeki kopyaları önlemek istiyorsanız @Pointy ve @Phrogz'u tercih ederim


3

Her gün tek hatlı çözümler oluşturun.

Dizilerdeki değerler tamamen rastgeledir, bu nedenle bu parçacıkları kullanacağınız zaman farklı olacaktır.

Küçük harfli rastgele karakterler içeren bir dizi (uzunluk 10)

Array.apply(null, Array(10)).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); })

['k', 'a', 'x', 'y', 'n', 'w', 'm', 'q', 'b', 'j']

0'dan 99'a kadar rastgele tam sayılara sahip bir dizi (uzunluk 10)

Array.apply(null, Array(10)).map(function() { return Math.floor(Math.random() * 100 % 100); })

[86, 77, 83, 27, 79, 96, 67, 75, 52, 21]

Bir dizi rastgele tarihler (10 yıl öncesinden bugüne)

Array.apply(null, Array(10)).map(function() { return new Date((new Date()).getFullYear() - Math.floor(Math.random() * 10), Math.floor(Math.random() * 12), Math.floor(Math.random() * 29) )})

[2008-08-22T21: 00: 00.000Z, 2007-07-17T21: 00: 00.000Z,
2015-05-05T21: 00: 00.000Z, 2011-06-14T21: 00: 00.000Z,
2009-07-23T21 : 00: 00.000Z, 2009-11-13T22: 00: 00.000Z,
2010-05-09T21: 00: 00.000Z, 2008-01-05T22: 00: 00.000Z,
2016-05-06T21: 00: 00.000Z, 2014-08-06T21: 00: 00.000Z]

Bir dizi (uzunluk 10) rastgele dizeler

Array.apply(null, Array(10)).map(function() { return Array.apply(null, Array(Math.floor(Math.random() * 10  + 3))).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); }).join('') });

['cubjjhaph', 'bmwy', 'alhobd', 'ceud', 'tnyullyn', 'vpkdflarhnf', 'hvg', 'arazuln', 'jzz', 'cyx']

Burada bulabileceğiniz diğer yararlı şeyler https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js


1

Bazı yeni ES6 özelliklerini kullanarak, bu artık aşağıdakiler kullanılarak gerçekleştirilebilir:

function getRandomInt(min, max) {
    "use strict";
    if (max < min) {
        // Swap min and max
        [min, max] = [min, max];
    }

    // Generate random number n, where min <= n <= max
    let range = max - min + 1;
    return Math.floor(Math.random() * range) + min;
}

let values = Array.from({length: 40}, () => getRandomInt(0, 40));

console.log(values);

Bu çözümün yalnızca şu ES6 özelliklerini destekleyen modern tarayıcılarda çalışacağını unutmayın: ok işlevleri ve Array.from ().


1

Aşağıya bakın: -

let arr = Array.apply(null, {length: 1000}).map(Function.call, Math.random)
/* will create array with 1000 elements */

0

@Phrogz tarafından önerilen sayfadan

for (var i=0,nums=[];i<49;i++) nums[i]={ n:i, rand:Math.random() };
nums.sort( function(a,b){ a=a.rand; b=b.rand; return a<b?-1:a>b?1:0 } );

0

Bu çözümlerin verdiğinden biraz farklı bir şeye ihtiyacım vardı, çünkü belirli bir aralıkta tutulan bir dizi farklı rastgele sayı ile bir dizi oluşturmam gerekiyordu. Çözümüm aşağıdadır.

function getDistinctRandomIntForArray(array, range){
   var n = Math.floor((Math.random() * range));
   if(array.indexOf(n) == -1){        
    return n; 
   } else {
    return getDistinctRandomIntForArray(array, range); 
   }
}

function generateArrayOfRandomInts(count, range) {
   var array = []; 
   for (i=0; i<count; ++i){
    array[i] = getDistinctRandomIntForArray(array, range);
   };
   return array; 
}

Çok fazla gereksiz aramayla sonuçlanma olasılığı olan bir döngü oluşturmamayı tercih ederdim (sayınız ve menziliniz yüksekse ve aynı sayıya yakınsa) ama bulabildiğim en iyisi bu.


0
function shuffle(maxElements) {
    //create ordered array : 0,1,2,3..maxElements
    for (var temArr = [], i = 0; i < maxElements; i++) {
        temArr[i] = i;
    }

    for (var finalArr = [maxElements], i = 0; i < maxElements; i++) {
        //remove rundom element form the temArr and push it into finalArrr
        finalArr[i] = temArr.splice(Math.floor(Math.random() * (maxElements - i)), 1)[0];
    }

    return finalArr
}

Sanırım bu yöntem sorunu olasılıklar ile çözecek, sadece rastgele sayı oluşturucu ile sınırlı.


0

0 ... uzunluk aralığından rastgele benzersiz değerlere ihtiyacınız varsa:

const randomRange = length => {
  const results = []
  const possibleValues = Array.from({ length }, (value, i) => i)

  for (let i = 0; i < length; i += 1) {
    const possibleValuesRange = length - (length - possibleValues.length)
    const randomNumber = Math.floor(Math.random() * possibleValuesRange)
    const normalizedRandomNumber = randomNumber !== possibleValuesRange ? randomNumber : possibleValuesRange

    const [nextNumber] = possibleValues.splice(normalizedRandomNumber, 1)

    results.push(nextNumber)
  }

  return results
}

randomRange(5) // [3, 0, 1, 4, 2]

0

Hiç tekrar etmeden rastgele dizinizi oluşturmanın en kısa yolunun bu olduğundan oldukça eminim.

var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5);

"oldukça emin", nasıl kullanma hakkında keysişlevi: Array.from(Array(40).keys()).sort(_ => Math.random() - .5)? Hatta delirebilir ve yayma operatörünü kullanabilirsiniz! Ama şu anda bu benim için çok heyecan verici.
Yeti

0

Partiye biraz geç kaldım ama rastgelelik için randojs.com'u kullanıyorum çünkü bu tür şeyleri süper kolaylaştırıyor. Bunun gibi 0'dan 39'a kadar rastgele karıştırılmış bir sayı dizisi elde edebilirsiniz:

console.log(randoSequence(40));
<script src="https://randojs.com/1.0.0.js"></script>

Tüm bunların lojistiği ile uğraşmak yok - ayrıca süper okunabilir ve anlaşılması kolay :)


0

Jeneratörler

@Phrogz ve @Jared Beck'in açıkladığı gibi, değerleri tekrarlamadan 40 rastgele olası değerden (0-39) oluşan 40 uzunluğunda bir dizi karıştırmak daha iyidir. Sadece kayıtlar için başka bir yaklaşım, jeneratörler kullanmak olabilir. Ancak bu yaklaşım, önerilen diğer çözümlere kıyasla performanstan yoksundur .

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];

0

Aşağıda, bir min ve maks'a izin veren ve minimumdan maksimuma kadar tüm sayıları içeren rastgele sırayla benzersiz değerler dizisi oluşturan bir ES6 işlevi verilmiştir:

const createRandomNumbers = (min, max) => {
  const randomNumbers = new Set()
  const range = max - min + 1

  while (randomNumbers.size < range) {
    randomNumbers.add(~~(Math.random() * range))
  }

  return [...randomNumbers]
}

0

Bundan *daha yüksek önceliğe sahip olduğu için |, |0değiştirmek için kullanarak daha kısa olabilir Math.floor().

[...Array(40)].map(e=>Math.random()*40|0)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.