Buat array dengan nilai acak


Jawaban:


53

Berikut adalah solusi yang mengacak daftar nomor unik (tidak ada pengulangan, selamanya).

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);

Jika Anda ingin mengizinkan nilai berulang (yang tidak diinginkan OP) maka cari di tempat lain. :)


4
Solusi ini bagus jika angkanya harus unik, tetapi ini adalah hal statistik / probabilistik yang sama sekali berbeda. Saya berharap ini jelas bagi OP dan tidak relevan dengan kasus mereka, tetapi dalam kasus tertentu dapat berdampak besar pada kebenaran program. (Saya tidak mengkritik jawabannya, hanya mengibarkan bendera untuk pembaca yang akan datang. Anda mungkin ingin menyebutkannya.) Lihat juga: en.wikipedia.org/wiki/Combination (perbedaan antara "dengan" atau "tanpa pengulangan"
chiccodoro

var random_array = new Array (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0.5); Saya pikir ini melakukan hal yang sama seperti di atas
Jamie337nichols

Bagaimana cara mengecualikannya agar tidak menghasilkan angka 0?
Gosi

208

Pendekatan terpendek (ES6)

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

Nikmati!


Kamu benar. Menghapus komentar saya. Versi yang diperbaiki dari cara terpendek sebenarnya: [... Array (20)]. Map (() => {return Math.floor (Math.random () * 30)});
jaheraho

7
Jika kami menghapus spasi dari pendekatan jawaban, itu 4 karakter lebih sedikit dari yang Anda usulkan. Tentu saja, jika Anda tertarik untuk bermain golf, Anda sebenarnya meninggalkan beberapa cara pintas pemotongan karakter yang mudah: [...Array(40)].map(_=>Math.ceil(Math.random()*40));akan menjadi 11 karakter lebih sedikit dari Anda, dan 7 lebih sedikit dari aslinya.
Kyle Baker

(tidak cukup cepat untuk mengoreksi - harus * 39 untuk memenuhi kriteria OP jika kami menggunakan Math.ceil, meskipun kami memotong 0 sebagai opsi. Jika kami dapat menerima 1-40 daripada 0-39, ini berfungsi. , kurangi karakter peningkatan untuk kembali ke Math.floor)
Kyle Baker

unggul !!! terima kasih telah berbagi
Adriel Werlich

43

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
Ada apa dengan argumen _dan i? tidak perlu di ES6 kecuali saya salah.
AfricanMatt

2
@AfricanMatt, _adalah elemen saat ini dan imerupakan indeks saat ini. Anda benar, mereka tidak diperlukan dalam kedua kasus tersebut. Anda dapat menghapusnya jika Anda suka.
Eugene Kulabuhov

1
Saya tidak tahu di mana Anda percaya bahwa versi untuk ES6 berfungsi? Array.from bekerja ... berikut adalah contoh dengan kode Anda ... randomArray = (length: number, max: number) => Array.from ({length}) .map (() => Math.floor (Math .random () * max));
Christian Matthew

31

Pendekatan ES6 yang lebih pendek:

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

Selain itu, Anda dapat memiliki fungsi dengan argumen:

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

1
.fill () membutuhkan parameter nilai
Damian Green

4
@DamianGreen - .fill()tanpa parameter apa pun akan mengisi array dengan undefined, yang merupakan satu-satunya hal yang diperlukan di sini .map()agar berfungsi
vsync

@ Damjan apakah ada cara untuk tidak mengulang nomor? Menyukai pendekatan ini
Henrique

@Henrique menggunakan variabel? 🤔
Sebj

@Sebj apakah itu mungkin? Maksud saya, pendekatan apa pun yang pendek seperti ini dan dengan alat peraga sebagai panjang dan maksimal akan bekerja dengan sempurna untuk saya :)
Henrique


16

Math.random()akan mengembalikan angka antara 0 dan 1 (eksklusif). Jadi, jika Anda ingin 0-40, Anda dapat mengalikannya dengan 40, hasil yang paling tinggi adalah hasil perkalian Anda.

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
Untuk memperjelas: itu adalah huruf L, bukan angka 1, di "l = 40", "i <l" dan "Math.random () * l". Font membuatnya sulit untuk dikatakan.
Mu Pikiran

11

.. array yang saya dapatkan sangat sedikit diacak. Ini menghasilkan banyak blok angka berurutan ...

Urutan item acak sering kali berisi blok nomor berurutan, lihat Kekeliruan Penjudi . Sebagai contoh:

.. kita baru saja melempar empat kepala berturut-turut .. Karena kemungkinan menjalankan lima kepala berturut-turut hanya 1⁄32 .. seseorang yang tunduk pada kesalahan penjudi mungkin percaya bahwa lemparan berikutnya ini lebih kecil kemungkinannya untuk menjadi kepala daripada menjadi ekor. http://en.wikipedia.org/wiki/Gamblers_fallacy


+1 persis. Seseorang perlu memutuskan apakah seseorang membutuhkan bilangan acak (secara statistik), atau bilangan yang "terlihat acak".
chiccodoro

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

membatasi larik menjadi 6 nilai agar mudah dilihat.


4

Karena kisaran angka dibatasi, saya akan mengatakan hal terbaik untuk dilakukan adalah menghasilkan array, mengisinya dengan angka nol hingga 39 (secara berurutan), lalu mengocoknya.


Berikut visualisasi teknik ini (meskipun halaman yang menggunakan sebuah mengerikan algoritma acak ).
Phrogz

Saya tidak tahu bahwa dia menginginkan setiap nomor di antara, melainkan sepenuhnya acak? Jika dia baik-baik saja dengan urutan acak, nilai statis maka ini akan berfungsi dengan baik.
Robert

yang mungkin melakukan pekerjaan itu, tetapi akan memberikan hasil yang sedikit berbeda dibandingkan jika Anda menggunakan Math.random()40 kali, karena ini akan memaksa setiap nomor muncul sekali dan tidak ada pengulangan.
Mu Pikiran

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

Ini di atas adalah cara tradisional untuk melakukannya tetapi saya kedua @Pointy dan @Phrogz jika Anda ingin menghindari duplikat dalam array Anda tanpa harus melakukan komputasi yang mahal


3

Buat solusi satu baris unik setiap hari.

Nilai dalam array adalah acak total, jadi ketika Anda akan menggunakan potongan ini, itu akan berbeda.

Larik (panjang 10) dengan karakter acak dalam huruf kecil

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']

Larik (panjang 10) dengan bilangan bulat acak dari 0 hingga 99

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

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

Tanggal acak array (dari 10 tahun lalu hingga sekarang)

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, 06-08-2014T21: 00: 00.000Z]

Sebuah array (panjang 10) string acak

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']

Hal berguna lainnya yang dapat Anda temukan di sini https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js


1

Menggunakan beberapa fitur ES6 baru, ini sekarang dapat dicapai dengan menggunakan:

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);

Perhatikan bahwa solusi ini hanya akan berfungsi di browser modern yang mendukung fitur ES6 ini: fungsi panah dan Array.from ().


1

Lihat di bawah: -

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

0

dari halaman yang disarankan oleh @Phrogz

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

Saya membutuhkan sesuatu yang sedikit berbeda dari apa yang diberikan solusi ini, karena saya perlu membuat array dengan sejumlah angka acak berbeda yang dipegang pada kisaran tertentu. Di bawah ini adalah solusi saya.

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; 
}

Saya lebih suka untuk tidak membuat loop yang memiliki kemungkinan untuk berakhir dengan banyak panggilan yang tidak perlu (jika hitungan Anda, dan jangkauannya tinggi dan dekat dengan nomor yang sama) tetapi ini adalah yang terbaik yang bisa saya dapatkan.


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
}

Saya kira metode ini akan menyelesaikan masalah dengan probabilitas, hanya dibatasi oleh generator angka acak.


0

Jika Anda membutuhkannya dengan nilai unik acak dari 0 ... rentang panjang:

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

Saya cukup yakin bahwa ini adalah cara terpendek untuk membuat array acak Anda tanpa pengulangan

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

"cukup yakin", bagaimana kalau menggunakan keysfungsi Array.from(Array(40).keys()).sort(_ => Math.random() - .5):? Anda bahkan mungkin menjadi gila, dan menggunakan operator penyebaran! Tapi itu terlalu mengasyikkan bagiku sekarang.
Yeti

0

Agak terlambat ke pesta, tapi saya menggunakan randojs.com untuk keacakan karena membuat hal-hal seperti ini sangat mudah. Anda bisa mendapatkan deretan angka yang diacak secara acak dari 0 hingga 39 seperti ini:

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

Tidak ada masalah dengan logistik semuanya - plus itu sangat mudah dibaca dan mudah dimengerti :)


0

Generator

Sebuah array dengan panjang 40 dari 40 nilai kemungkinan acak (0 - 39) tanpa nilai pengulangan lebih baik untuk diacak seperti yang dijelaskan @Phrogz dan @Jared Beck. Pendekatan lain, hanya untuk catatan, bisa menggunakan generator. Tetapi pendekatan ini kurang memiliki kinerja dibandingkan dengan solusi lain yang diusulkan .

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.