Tạo một mảng với các giá trị ngẫu nhiên


100

Làm cách nào để tạo một mảng có 40 phần tử, với các giá trị ngẫu nhiên từ 0 đến 39? Giống

[4, 23, 7, 39, 19, 0, 9, 14, ...]

Tôi đã thử sử dụng các giải pháp từ đây:

http://freewebdesigntutorials.com/javaScriptTutorials/jsArrayObject/randomizeArrayElements.htm

nhưng mảng tôi nhận được là rất ít ngẫu nhiên. Nó tạo ra rất nhiều khối các số liên tiếp ...

Câu trả lời:


53

Đây là một giải pháp xáo trộn danh sách các số duy nhất (không bao giờ lặp lại).

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

Nếu bạn muốn cho phép các giá trị lặp lại (không phải là những gì OP muốn) thì hãy tìm ở nơi khác. :)


4
Giải pháp này là tốt nếu các con số phải là duy nhất, nhưng đây là một điều hoàn toàn khác về thống kê / xác suất. Tôi hy vọng điều này đã rõ ràng với OP và không liên quan trong trường hợp của họ, nhưng trong một số trường hợp nhất định, nó có thể có tác động lớn đến tính đúng đắn của chương trình. (Tôi không chỉ trích câu trả lời, chỉ là một lá cờ cho những độc giả trong tương lai. Bạn có thể muốn đề cập đến điều đó.) Xem thêm: en.wikipedia.org/wiki/Combination (phân biệt giữa "với" hoặc "không lặp lại"
chiccodoro

var random_array = new Array (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0.5); Tôi nghĩ rằng đây không giống như ở trên
Jamie337nichols

Làm thế nào để loại trừ nó khỏi việc tạo ra số 0?
Gosi 19/09/19

208

Cách tiếp cận ngắn nhất (ES6)

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

Thưởng thức!


Bạn đúng rồi. Đã xóa bình luận của tôi. Phiên bản đã sửa của đường ngắn nhất thực tế: [... Array (20)]. Map (() => {return Math.floor (Math.random () * 30)});
jaheraho

7
Nếu chúng tôi xóa khoảng trắng khỏi cách tiếp cận của câu trả lời, nó sẽ ít hơn 4 ký tự so với ký tự bạn đề xuất. Tất nhiên, nếu bạn quan tâm đến việc chơi gôn, bạn thực sự đã bỏ qua một số phím tắt dễ dàng cắt ký tự: [...Array(40)].map(_=>Math.ceil(Math.random()*40));sẽ ít hơn 11 ký tự so với của bạn và ít hơn 7 ký tự so với ban đầu.
Kyle Baker

(không đủ nhanh để sửa - cần phải là * 39 để đáp ứng tiêu chí của OP nếu chúng tôi sử dụng Math.ceil, mặc dù chúng tôi đã loại bỏ 0 làm tùy chọn. Nếu chúng tôi có thể chấp nhận 1-40 thay vì 0-39, điều này sẽ hoạt động. Ngược lại , giảm một nhân vật cải thiện cho sẽ trở lại Math.floor)
Kyle Baker

xuất sắc !!! cảm ơn vì đã chia sẻ
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
Có gì với các _và các iđối số? không cần thiết trong ES6 trừ khi tôi nhầm.
AfricanMatt

2
@AfricanMatt, _là phần tử hiện tại và ilà chỉ mục hiện tại. Bạn nói đúng, chúng đều không cần thiết trong cả hai trường hợp. Bạn có thể loại bỏ chúng nếu bạn muốn.
Eugene Kulabuhov 10/02/17

1
Tôi không biết bạn tin rằng phiên bản cho ES6 hoạt động ở đâu? Array.from hoạt động ... đây là một ví dụ với mã của bạn ... randomArray = (length: number, max: number) => Array.from ({length}) .map (() => Math.floor (Math .random () * max));
Christian Matthew

31

Cách tiếp cận ES6 ngắn hơn nữa:

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

Ngoài ra, bạn có thể có một hàm với các đối số:

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

1
.fill () yêu cầu một tham số giá trị
Damian Green

4
@DamianGreen - .fill()mà không cần bất kỳ thông số sẽ điền vào các mảng với undefined, đó là điều duy nhất cần thiết vào đây để .map()làm việc
vsync

@Damjan có cách nào để không lặp lại số không? Thích cách tiếp cận này
Henrique

@Henrique sử dụng biến? 🤔
Sebj

@Sebj có được không? Ý tôi là, bất kỳ cách tiếp cận nào ngắn như thế này và với đạo cụ là chiều dài và tối đa sẽ hoạt động hoàn hảo đối với tôi :)
Henrique

31

Ngắn nhất :-)

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


18
~~là viết tắt của Math.floor
Curt

1
điều đó thật tuyệt; có sự ủng hộ rộng rãi cho ~~cách viết tắt đó không? (chỉnh sửa: ahh, nó chỉ là một nhà điều hành Bitwise , tôi nhìn thấy)
Rafe Goldberg

@Curt chỉ dành cho số dương
AJ Uppal

16

Math.random()sẽ trả về một số từ 0 đến 1 (độc quyền). Vì vậy, nếu bạn muốn 0-40, bạn có thể nhân nó với 40, kết quả cao nhất có thể là số bạn đang nhân với.

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
Để làm rõ: đó là một chữ cái L, không phải số 1, trong "l = 40", "i <l" và "Math.random () * l". Phông chữ làm cho nó khó nhận biết.
Mu Mind

11

.. mảng tôi nhận được là rất ít ngẫu nhiên. Nó tạo ra rất nhiều khối các số liên tiếp ...

Chuỗi các mục ngẫu nhiên thường chứa các khối số liên tiếp, hãy xem Sai lầm của người chơi cờ bạc . Ví dụ:

.. chúng tôi vừa tung bốn đầu liên tiếp .. Vì xác suất xảy ra năm đầu liên tiếp chỉ là 1⁄32 .. một người theo sự ngụy biện của con bạc có thể tin rằng lần lật tiếp theo này ít có khả năng bị lật hơn thành đuôi. http://en.wikipedia.org/wiki/Gamblers_fallacy


+1 chính xác. Người ta cần quyết định xem người ta cần các số ngẫu nhiên thực (theo thống kê) hay các số "trông ngẫu nhiên".
chiccodoro

4

Vì phạm vi số bị hạn chế, tôi muốn nói điều tốt nhất nên làm là tạo mảng, điền nó bằng các số từ 0 đến 39 (theo thứ tự), sau đó xáo trộn nó.



Tôi không biết rằng anh ta muốn mọi con số giữa, nhưng hoàn toàn ngẫu nhiên? Nếu anh ấy ổn với thứ tự ngẫu nhiên, các giá trị tĩnh thì điều này sẽ hoạt động tốt.
Robert

mà có thể thực hiện công việc, nhưng sẽ cho kết quả hơi khác so với nếu bạn đã sử dụng Math.random()40 lần, vì nó sẽ thực thi mỗi số xuất hiện một lần và không lặp lại.
Mu Mind

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

giới hạn mảng ở 6 giá trị để dễ nhìn.


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

Đây là cách làm truyền thống nhưng tôi thứ hai @Pointy và @Phrogz nếu bạn muốn tránh trùng lặp trong mảng của mình mà không cần phải tính toán tốn kém


3

Các giải pháp đơn hàng khó giải quyết mỗi ngày.

Các giá trị trong mảng là hoàn toàn ngẫu nhiên, vì vậy khi bạn sử dụng các đoạn mã này, nó sẽ khác.

Một mảng (độ dài 10) với các ký tự ngẫu nhiên ở dạng chữ thường

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

Một mảng (độ dài 10) với các số nguyên ngẫu nhiên từ 0 đến 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]

Một mảng ngày ngẫu nhiên (từ 10 năm trước đến nay)

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]

Một mảng (độ dài 10) chuỗi ngẫu nhiên

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

Những điều hữu ích khác bạn có thể tìm thấy ở đây https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js


1

Sử dụng một số tính năng mới của ES6, điều này hiện có thể đạt được bằng cách sử dụng:

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

Lưu ý rằng giải pháp này sẽ chỉ hoạt động trong các trình duyệt hiện đại hỗ trợ các tính năng ES6 này: các hàm mũi tên và Array.from ().


1

Tham khảo bên dưới: -

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

0

từ trang do @Phrogz đề xuất

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

Tôi cần một cái gì đó khác một chút so với những gì các giải pháp này đưa ra, trong đó tôi cần tạo một mảng với một số số ngẫu nhiên riêng biệt được giữ trong một phạm vi xác định. Dưới đây là giải pháp của tôi.

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

Tôi sẽ không muốn tạo một vòng lặp có khả năng kết thúc bằng nhiều cuộc gọi không cần thiết (nếu số lượng và phạm vi của bạn cao và gần bằng cùng một số) nhưng đây là cách tốt nhất mà tôi có thể nghĩ ra.


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
}

Tôi đoán phương pháp này sẽ giải quyết vấn đề với các xác suất, chỉ bị giới hạn bởi trình tạo số ngẫu nhiên.


0

Nếu bạn cần nó với các giá trị duy nhất ngẫu nhiên từ 0 ... dải độ dài:

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

Tôi khá chắc rằng đây là cách ngắn nhất để tạo mảng ngẫu nhiên của bạn mà không có bất kỳ sự lặp lại nào

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

"khá chắc chắn", làm thế nào về sử dụng keyshàm Array.from(Array(40).keys()).sort(_ => Math.random() - .5):? Bạn thậm chí có thể phát điên và sử dụng toán tử spread! Nhưng điều đó là quá thú vị đối với tôi lúc này.
Yeti

0

Đến bữa tiệc hơi muộn, nhưng tôi sử dụng randojs.com vì ngẫu nhiên vì nó làm cho những thứ như thế này trở nên siêu dễ dàng. Bạn có thể nhận được một dãy số được xáo trộn ngẫu nhiên từ 0 đến 39 giống như sau:

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

Không phiền phức với hậu cần của tất cả- cộng với nó siêu dễ đọc và dễ hiểu :)


0

Máy phát điện

Một mảng có độ dài 40 trong số 40 giá trị ngẫu nhiên có thể có (0 - 39) không có giá trị lặp lại thì tốt hơn nên xáo trộn nó như @Phrogz và @Jared Beck giải thích. Một cách tiếp cận khác, chỉ dành cho các bản ghi, có thể là sử dụng máy phát điện. Nhưng cách tiếp cận này thiếu hiệu quả so với các giải pháp được đề xuất khác .

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.