Trying to get only one value out of an array [duplicate] - javascript

Consider:
var myArray = ['January', 'February', 'March'];
How can I select a random value from this array using JavaScript?

It's a simple one-liner:
const randomElement = array[Math.floor(Math.random() * array.length)];
For example:
const months = ["January", "February", "March", "April", "May", "June", "July"];
const random = Math.floor(Math.random() * months.length);
console.log(random, months[random]);

If you've already got underscore or lodash included in your project you can use _.sample.
// will return one item randomly from the array
_.sample(['January', 'February', 'March']);
If you need to get more than one item randomly, you can pass that as a second argument in underscore:
// will return two items randomly from the array using underscore
_.sample(['January', 'February', 'March'], 2);
or use the _.sampleSize method in lodash:
// will return two items randomly from the array using lodash
_.sampleSize(['January', 'February', 'March'], 2);

You may consider defining a function on the Array prototype, in order to create a method [].sample() which returns a random element.
First, to define the prototype function, place this snippet in your code:
Array.prototype.sample = function(){
return this[Math.floor(Math.random()*this.length)];
}
Later, to sample a random element from the array, just call .sample():
[1,2,3,4].sample() //=> a random element
I'm releasing these code snippets into the public domain, under the terms of the CC0 1.0 license.

~~ is much faster than Math.Floor(), so when it comes to performance optimization while producing output using UI elements, ~~ wins the game. MORE INFO
var rand = myArray[~~(Math.random() * myArray.length)];
But if you know that the array is going to have millions of elements then you might want to reconsider between Bitwise Operator and Math.Floor(), as bitwise operators behave weirdly with large numbers. See below example explained with the output.
var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343

The shortest version:
var myArray = ['January', 'February', 'March'];
var rand = myArray[(Math.random() * myArray.length) | 0]
console.log(rand)

Say you want to choose a random item that is different from the last time (not really random, but still a common requirement)...
/**
* Return a random element from an array that is
* different than `last` (as long as the array has > 1 items).
* Return null if the array is empty.
*/
function getRandomDifferent(arr, last = undefined) {
if (arr.length === 0) {
return null;
} else if (arr.length === 1) {
return arr[0];
} else {
let num = 0;
do {
num = Math.floor(Math.random() * arr.length);
} while (arr[num] === last);
return arr[num];
}
}
Implement like this:
const arr = [1,2,3];
const r1 = getRandomDifferent(arr);
const r2 = getRandomDifferent(arr, r1); // r2 is different than r1.

If you have fixed values (like a month name list) and want a one-line solution
var result = ['January', 'February', 'March'][Math.floor(Math.random() * 3)]
The second part of the array is an access operation as described in Why does [5,6,8,7][1,2] = 8 in JavaScript?

If you want to write it on one line, like Pascual's solution, another solution would be to write it using ES6's find function (based on the fact, that the probability of randomly selecting one out of n items is 1/n):
var item = ['A', 'B', 'C', 'D'].find((_, i, ar) => Math.random() < 1 / (ar.length - i));
console.log(item);
Use that approach for testing purposes and if there is a good reason to not save the array in a seperate variable only. Otherwise the other answers (floor(random()*length and using a seperate function) are your way to go.

Faker.js has many utility functions for generating random test data. It is a good option in the context of a test suite:
const faker = require('faker');
faker.helpers.arrayElement(['January', 'February', 'March']);
As commenters have mentioned, you generally should not use this library in production code.

Editing Array prototype can be harmful. Here it is a simple function to do the job.
function getArrayRandomElement (arr) {
if (arr && arr.length) {
return arr[Math.floor(Math.random() * arr.length)];
}
// The undefined will be returned if the empty array was passed
}
Usage:
// Example 1
var item = getArrayRandomElement(['January', 'February', 'March']);
// Example 2
var myArray = ['January', 'February', 'March'];
var item = getArrayRandomElement(myArray);

If you need to fetch a random item more than once, then, obviously you would use a function. One way is to make that function a method of the Array.prototype, but that will normally get you shouted down for tampering with built in prototypes.
However, you can add the method to the specific array itself:
var months = ['January', 'February', 'March'];
months.random = function() {
return this[Math.floor(Math.random()*this.length)];
};
That way you can use months.random() as often as you like without interfering with the generic Array.prototype.
As with any random function, you run the risk of getting the same value successively. If you don’t want that, you will need to track the previous value with another property:
months.random=function() {
var random;
while((random=this[Math.floor(Math.random()*this.length)]) == this.previous);
this.previous=random;
return random;
};
If you’re going to do this sort of thing often, and you don’t want to tamper with Array.prototype, you can do something like this:
function randomValue() {
return this[Math.floor(Math.random()*this.length)];
}
var data = [ … ];
var moreData = [ … ];
data.random=randomValue;
moreData.random=randomValue;

Many of the offered solutions add a method to a specific Array which restricts it's use to just that array. This solution is reusable code that works for any array and can be made type safe.
TypeScript
export function randChoice<T>(arr: Array<T>): T {
return arr[Math.floor(Math.random() * arr.length)]
}
JavaScript
export function randChoice(arr) {
return arr[Math.floor(Math.random() * arr.length)]
}

To get crypto-strong random item form array use
let rndItem = a=> a[rnd()*a.length|0];
let rnd = ()=> crypto.getRandomValues(new Uint32Array(1))[0]/2**32;
var myArray = ['January', 'February', 'March'];
console.log( rndItem(myArray) )

Recursive, standalone function which can return any number of items (identical to lodash.sampleSize):
function getRandomElementsFromArray(array, numberOfRandomElementsToExtract = 1) {
const elements = [];
function getRandomElement(arr) {
if (elements.length < numberOfRandomElementsToExtract) {
const index = Math.floor(Math.random() * arr.length)
const element = arr.splice(index, 1)[0];
elements.push(element)
return getRandomElement(arr)
} else {
return elements
}
}
return getRandomElement([...array])
}

This is similar to, but more general than, #Jacob Relkin's solution:
This is ES2015:
const randomChoice = arr => {
const randIndex = Math.floor(Math.random() * arr.length);
return arr[randIndex];
};
The code works by selecting a random number between 0 and the length of the array, then returning the item at that index.

var item = myArray[Math.floor(Math.random()*myArray.length)];
or equivalent shorter version:
var item = myArray[(Math.random()*myArray.length)|0];
Sample code:
var myArray = ['January', 'February', 'March'];
var item = myArray[(Math.random()*myArray.length)|0];
console.log('item:', item);

Simple Function :
var myArray = ['January', 'February', 'March'];
function random(array) {
return array[Math.floor(Math.random() * array.length)]
}
random(myArray);
OR
var myArray = ['January', 'February', 'March'];
function random() {
return myArray[Math.floor(Math.random() * myArray.length)]
}
random();
OR
var myArray = ['January', 'February', 'March'];
function random() {
return myArray[Math.floor(Math.random() * myArray.length)]
}
random();

In my opinion, better than messing around with prototypes , or declaring it just in time, I prefer exposing it to window:
window.choice = function() {
if (!this.length || this.length == 0) return;
if (this.length == 1) return this[0];
return this[Math.floor(Math.random()*this.length)];
}
Now anywhere on your app you call it like:
var rand = window.choice.call(array)
This way you can still use for(x in array) loop properly

I've found a way around the top answer's complications, just by concatenating the variable rand to another variable that allows that number to be displayed inside the calling of myArray[];. By deleting the new array created and toying around with it's complications, I've come up with a working solution:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var myArray = ['January', 'February', 'March', 'April', 'May'];
var rand = Math.floor(Math.random() * myArray.length);
var concat = myArray[rand];
function random() {
document.getElementById("demo").innerHTML = (concat);
}
</script>
<button onClick="random();">
Working Random Array generator
</button>
</body>
</html>

static generateMonth() {
const theDate = ['January', 'February', 'March'];
const randomNumber = Math.floor(Math.random()*3);
return theDate[randomNumber];
};
You set a constant variable to the array, you then have another constant that chooses randomly between the three objects in the array and then the function simply returns the results.

Looking for a true one-liner I came to this:
['January', 'February', 'March'].reduce((a, c, i, o) => { return o[Math.floor(Math.random() * Math.floor(o.length))]; })

By adding a method on prototype of array you can get random values easly.
In this example you can get single or multiple random values from array.
You can run to test code by clicking snippet button.
Array.prototype.random = function(n){
if(n&&n>1){
const a = [];
for(let i = 0;i<n;i++){
a.push(this[Math.floor(Math.random()*this.length)]);
}
return a;
} else {
return this[Math.floor(Math.random()*this.length)];
}
}
const mySampleArray = ['a','b','c','d','e','f','g','h'];
mySampleArray.random(); // return any random value etc. 'a', 'b'
mySampleArray.random(3); //retun an array with random values etc: ['b','f','a'] , ['d','b','d']
alert(mySampleArray.random());
alert(mySampleArray.random(3));

Method 1:
Use Math.random() function to get the random number between(0-1, 1
exclusive).
Multiply it by the array length to get the numbers
between(0-arrayLength).
Use Math.floor() to get the index ranging
from(0 to arrayLength-1).
const arr = ["foo","bar"];
const randomlyPickedString=arr[Math.floor(Math.random() * arr.length)];
console.log(randomlyPickedString);
Method 2:
The random(a, b) method is used to generates a number between(a to b, b exclusive).
Taking the floor value to range the numbers from (1 to arrayLength).
Subtract 1 to get the index ranging from(0 to arrayLength-1).
const arr = ["foo","bar"];
const randomlyPickedString=arr[Math.floor(random(1, 5))-1];
console.log(randomlyPickedString);

A generic way to get random element(s):
let some_array = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
let months = random_elems(some_array, 3);
console.log(months);
function random_elems(arr, count) {
let len = arr.length;
let lookup = {};
let tmp = [];
if (count > len)
count = len;
for (let i = 0; i < count; i++) {
let index;
do {
index = ~~(Math.random() * len);
} while (index in lookup);
lookup[index] = null;
tmp.push(arr[index]);
}
return tmp;
}

Here is an example of how to do it:
$scope.ctx.skills = data.result.skills;
$scope.praiseTextArray = [
"Hooray",
"You\'re ready to move to a new skill",
"Yahoo! You completed a problem",
"You\'re doing great",
"You succeeded",
"That was a brave effort trying new problems",
"Your brain was working hard",
"All your hard work is paying off",
"Very nice job!, Let\'s see what you can do next",
"Well done",
"That was excellent work",
"Awesome job",
"You must feel good about doing such a great job",
"Right on",
"Great thinking",
"Wonderful work",
"You were right on top of that one",
"Beautiful job",
"Way to go",
"Sensational effort"
];
$scope.praiseTextWord = $scope.praiseTextArray[Math.floor(Math.random()*$scope.praiseTextArray.length)];

Create one random value and pass to array
Please try following code..
//For Search textbox random value
var myPlaceHolderArray = ['Hotels in New York...', 'Hotels in San Francisco...', 'Hotels Near Disney World...', 'Hotels in Atlanta...'];
var rand = Math.floor(Math.random() * myPlaceHolderArray.length);
var Placeholdervalue = myPlaceHolderArray[rand];
alert(Placeholdervalue);

randojs makes this a little more simple and readable:
console.log( rando(['January', 'February', 'March']).value );
<script src="https://randojs.com/1.0.0.js"></script>

I am really surprised nobody tried to use native random values:
array[Date.now()%array.length]
It will not work for array length over 160000000000, but I am sure you will never create arrays like this
UPD
As far as you question is how to pick random value from array called myArray (with len=3), the solution should be:
myArray[Date.now()%myArray.length]

Related

Getting an array item [duplicate]

Consider:
var myArray = ['January', 'February', 'March'];
How can I select a random value from this array using JavaScript?
It's a simple one-liner:
const randomElement = array[Math.floor(Math.random() * array.length)];
For example:
const months = ["January", "February", "March", "April", "May", "June", "July"];
const random = Math.floor(Math.random() * months.length);
console.log(random, months[random]);
If you've already got underscore or lodash included in your project you can use _.sample.
// will return one item randomly from the array
_.sample(['January', 'February', 'March']);
If you need to get more than one item randomly, you can pass that as a second argument in underscore:
// will return two items randomly from the array using underscore
_.sample(['January', 'February', 'March'], 2);
or use the _.sampleSize method in lodash:
// will return two items randomly from the array using lodash
_.sampleSize(['January', 'February', 'March'], 2);
You may consider defining a function on the Array prototype, in order to create a method [].sample() which returns a random element.
First, to define the prototype function, place this snippet in your code:
Array.prototype.sample = function(){
return this[Math.floor(Math.random()*this.length)];
}
Later, to sample a random element from the array, just call .sample():
[1,2,3,4].sample() //=> a random element
I'm releasing these code snippets into the public domain, under the terms of the CC0 1.0 license.
~~ is much faster than Math.Floor(), so when it comes to performance optimization while producing output using UI elements, ~~ wins the game. MORE INFO
var rand = myArray[~~(Math.random() * myArray.length)];
But if you know that the array is going to have millions of elements then you might want to reconsider between Bitwise Operator and Math.Floor(), as bitwise operators behave weirdly with large numbers. See below example explained with the output.
var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343
The shortest version:
var myArray = ['January', 'February', 'March'];
var rand = myArray[(Math.random() * myArray.length) | 0]
console.log(rand)
Say you want to choose a random item that is different from the last time (not really random, but still a common requirement)...
/**
* Return a random element from an array that is
* different than `last` (as long as the array has > 1 items).
* Return null if the array is empty.
*/
function getRandomDifferent(arr, last = undefined) {
if (arr.length === 0) {
return null;
} else if (arr.length === 1) {
return arr[0];
} else {
let num = 0;
do {
num = Math.floor(Math.random() * arr.length);
} while (arr[num] === last);
return arr[num];
}
}
Implement like this:
const arr = [1,2,3];
const r1 = getRandomDifferent(arr);
const r2 = getRandomDifferent(arr, r1); // r2 is different than r1.
If you have fixed values (like a month name list) and want a one-line solution
var result = ['January', 'February', 'March'][Math.floor(Math.random() * 3)]
The second part of the array is an access operation as described in Why does [5,6,8,7][1,2] = 8 in JavaScript?
If you want to write it on one line, like Pascual's solution, another solution would be to write it using ES6's find function (based on the fact, that the probability of randomly selecting one out of n items is 1/n):
var item = ['A', 'B', 'C', 'D'].find((_, i, ar) => Math.random() < 1 / (ar.length - i));
console.log(item);
Use that approach for testing purposes and if there is a good reason to not save the array in a seperate variable only. Otherwise the other answers (floor(random()*length and using a seperate function) are your way to go.
Faker.js has many utility functions for generating random test data. It is a good option in the context of a test suite:
const faker = require('faker');
faker.helpers.arrayElement(['January', 'February', 'March']);
As commenters have mentioned, you generally should not use this library in production code.
Editing Array prototype can be harmful. Here it is a simple function to do the job.
function getArrayRandomElement (arr) {
if (arr && arr.length) {
return arr[Math.floor(Math.random() * arr.length)];
}
// The undefined will be returned if the empty array was passed
}
Usage:
// Example 1
var item = getArrayRandomElement(['January', 'February', 'March']);
// Example 2
var myArray = ['January', 'February', 'March'];
var item = getArrayRandomElement(myArray);
If you need to fetch a random item more than once, then, obviously you would use a function. One way is to make that function a method of the Array.prototype, but that will normally get you shouted down for tampering with built in prototypes.
However, you can add the method to the specific array itself:
var months = ['January', 'February', 'March'];
months.random = function() {
return this[Math.floor(Math.random()*this.length)];
};
That way you can use months.random() as often as you like without interfering with the generic Array.prototype.
As with any random function, you run the risk of getting the same value successively. If you don’t want that, you will need to track the previous value with another property:
months.random=function() {
var random;
while((random=this[Math.floor(Math.random()*this.length)]) == this.previous);
this.previous=random;
return random;
};
If you’re going to do this sort of thing often, and you don’t want to tamper with Array.prototype, you can do something like this:
function randomValue() {
return this[Math.floor(Math.random()*this.length)];
}
var data = [ … ];
var moreData = [ … ];
data.random=randomValue;
moreData.random=randomValue;
Many of the offered solutions add a method to a specific Array which restricts it's use to just that array. This solution is reusable code that works for any array and can be made type safe.
TypeScript
export function randChoice<T>(arr: Array<T>): T {
return arr[Math.floor(Math.random() * arr.length)]
}
JavaScript
export function randChoice(arr) {
return arr[Math.floor(Math.random() * arr.length)]
}
To get crypto-strong random item form array use
let rndItem = a=> a[rnd()*a.length|0];
let rnd = ()=> crypto.getRandomValues(new Uint32Array(1))[0]/2**32;
var myArray = ['January', 'February', 'March'];
console.log( rndItem(myArray) )
Recursive, standalone function which can return any number of items (identical to lodash.sampleSize):
function getRandomElementsFromArray(array, numberOfRandomElementsToExtract = 1) {
const elements = [];
function getRandomElement(arr) {
if (elements.length < numberOfRandomElementsToExtract) {
const index = Math.floor(Math.random() * arr.length)
const element = arr.splice(index, 1)[0];
elements.push(element)
return getRandomElement(arr)
} else {
return elements
}
}
return getRandomElement([...array])
}
This is similar to, but more general than, #Jacob Relkin's solution:
This is ES2015:
const randomChoice = arr => {
const randIndex = Math.floor(Math.random() * arr.length);
return arr[randIndex];
};
The code works by selecting a random number between 0 and the length of the array, then returning the item at that index.
var item = myArray[Math.floor(Math.random()*myArray.length)];
or equivalent shorter version:
var item = myArray[(Math.random()*myArray.length)|0];
Sample code:
var myArray = ['January', 'February', 'March'];
var item = myArray[(Math.random()*myArray.length)|0];
console.log('item:', item);
Simple Function :
var myArray = ['January', 'February', 'March'];
function random(array) {
return array[Math.floor(Math.random() * array.length)]
}
random(myArray);
OR
var myArray = ['January', 'February', 'March'];
function random() {
return myArray[Math.floor(Math.random() * myArray.length)]
}
random();
OR
var myArray = ['January', 'February', 'March'];
function random() {
return myArray[Math.floor(Math.random() * myArray.length)]
}
random();
In my opinion, better than messing around with prototypes , or declaring it just in time, I prefer exposing it to window:
window.choice = function() {
if (!this.length || this.length == 0) return;
if (this.length == 1) return this[0];
return this[Math.floor(Math.random()*this.length)];
}
Now anywhere on your app you call it like:
var rand = window.choice.call(array)
This way you can still use for(x in array) loop properly
I've found a way around the top answer's complications, just by concatenating the variable rand to another variable that allows that number to be displayed inside the calling of myArray[];. By deleting the new array created and toying around with it's complications, I've come up with a working solution:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var myArray = ['January', 'February', 'March', 'April', 'May'];
var rand = Math.floor(Math.random() * myArray.length);
var concat = myArray[rand];
function random() {
document.getElementById("demo").innerHTML = (concat);
}
</script>
<button onClick="random();">
Working Random Array generator
</button>
</body>
</html>
static generateMonth() {
const theDate = ['January', 'February', 'March'];
const randomNumber = Math.floor(Math.random()*3);
return theDate[randomNumber];
};
You set a constant variable to the array, you then have another constant that chooses randomly between the three objects in the array and then the function simply returns the results.
Looking for a true one-liner I came to this:
['January', 'February', 'March'].reduce((a, c, i, o) => { return o[Math.floor(Math.random() * Math.floor(o.length))]; })
By adding a method on prototype of array you can get random values easly.
In this example you can get single or multiple random values from array.
You can run to test code by clicking snippet button.
Array.prototype.random = function(n){
if(n&&n>1){
const a = [];
for(let i = 0;i<n;i++){
a.push(this[Math.floor(Math.random()*this.length)]);
}
return a;
} else {
return this[Math.floor(Math.random()*this.length)];
}
}
const mySampleArray = ['a','b','c','d','e','f','g','h'];
mySampleArray.random(); // return any random value etc. 'a', 'b'
mySampleArray.random(3); //retun an array with random values etc: ['b','f','a'] , ['d','b','d']
alert(mySampleArray.random());
alert(mySampleArray.random(3));
Method 1:
Use Math.random() function to get the random number between(0-1, 1
exclusive).
Multiply it by the array length to get the numbers
between(0-arrayLength).
Use Math.floor() to get the index ranging
from(0 to arrayLength-1).
const arr = ["foo","bar"];
const randomlyPickedString=arr[Math.floor(Math.random() * arr.length)];
console.log(randomlyPickedString);
Method 2:
The random(a, b) method is used to generates a number between(a to b, b exclusive).
Taking the floor value to range the numbers from (1 to arrayLength).
Subtract 1 to get the index ranging from(0 to arrayLength-1).
const arr = ["foo","bar"];
const randomlyPickedString=arr[Math.floor(random(1, 5))-1];
console.log(randomlyPickedString);
A generic way to get random element(s):
let some_array = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
let months = random_elems(some_array, 3);
console.log(months);
function random_elems(arr, count) {
let len = arr.length;
let lookup = {};
let tmp = [];
if (count > len)
count = len;
for (let i = 0; i < count; i++) {
let index;
do {
index = ~~(Math.random() * len);
} while (index in lookup);
lookup[index] = null;
tmp.push(arr[index]);
}
return tmp;
}
Here is an example of how to do it:
$scope.ctx.skills = data.result.skills;
$scope.praiseTextArray = [
"Hooray",
"You\'re ready to move to a new skill",
"Yahoo! You completed a problem",
"You\'re doing great",
"You succeeded",
"That was a brave effort trying new problems",
"Your brain was working hard",
"All your hard work is paying off",
"Very nice job!, Let\'s see what you can do next",
"Well done",
"That was excellent work",
"Awesome job",
"You must feel good about doing such a great job",
"Right on",
"Great thinking",
"Wonderful work",
"You were right on top of that one",
"Beautiful job",
"Way to go",
"Sensational effort"
];
$scope.praiseTextWord = $scope.praiseTextArray[Math.floor(Math.random()*$scope.praiseTextArray.length)];
Create one random value and pass to array
Please try following code..
//For Search textbox random value
var myPlaceHolderArray = ['Hotels in New York...', 'Hotels in San Francisco...', 'Hotels Near Disney World...', 'Hotels in Atlanta...'];
var rand = Math.floor(Math.random() * myPlaceHolderArray.length);
var Placeholdervalue = myPlaceHolderArray[rand];
alert(Placeholdervalue);
randojs makes this a little more simple and readable:
console.log( rando(['January', 'February', 'March']).value );
<script src="https://randojs.com/1.0.0.js"></script>
I am really surprised nobody tried to use native random values:
array[Date.now()%array.length]
It will not work for array length over 160000000000, but I am sure you will never create arrays like this
UPD
As far as you question is how to pick random value from array called myArray (with len=3), the solution should be:
myArray[Date.now()%myArray.length]

Create a functions, which creates a new array out of an existing one, which has less or equal amount of elements and no repeats

I have an array like this:
var arr = [0,1,2,3,4,5]
What I need is to write a function, which will generate a new array of random length (but less or equal than arr.length) and won't generate repeated numbers. Something like:
var arrNew = [2,4,0]
but not
var arrNew = [2,4,2,2,0]
I came up with this, but it generates repeated elements:
var list = [0,1,2,3,4,5];
var getRandomNumberRange = function (min, max) {
return Math.floor(Math.random() * (max - min) + min);
};
var getRandomArr = function (list) {
var arr = new Array(getRandomNumberRange(1, 6));
for (var i = 0; i < arr.length; i++) {
arr[i] = list[getRandomNumber(list.length)];
}
return arr;
};
Appreciate your help!
NOTE: there's nothing stopping this code from giving you an empty array as your random array.
var arr = [0,1,2,3,4,5, 36, 15, 25]
function generateRandomArrayFromSeed(arr) {
// Create a new set to keep track of what values we've used
const used = new Set();
// generate a new array.
const newArr = [];
// what random length will we be using today?
const newLength = getRandomNumber(arr.length);
// while our new array is still less than our newly randomized length, we run this block of code
while(newArr.length < newLength) {
// first, we generate a random index
const randomNumber = getRandomNumber(arr.length);
// then we check if the value at this index is in our set; if it is, we continue to the next iteration of the loop, and none of the remaining code is ran.
if(used.has(arr[randomNumber])) continue;
// otherwise, push this new value to our array
newArr.push(arr[randomNumber]);
// and update our used set by adding our random number
used.add(arr[randomNumber]);
}
// finally return this new random array.
return newArr;
}
function getRandomNumber(limit = 10) {
return Math.floor(Math.random() * limit);
}
console.log(generateRandomArrayFromSeed(arr));
Moving the data vrom an array datastructure to a Set could solve the problem.
Sets dont accept duplicate values.
For more on Set in javascript, see MDN here
To convert the Set back to an array, use Array.from()
To avoid duplicates in you final array just use Set and convert it back to an array using Array.from
Save you result inside set as below:
arr = Array.from(new Set(<result array>));

Convert number to a reversed array of digits

I've developed this codepen (http://codepen.io/PiotrBerebecki/pen/qZjojV?editors=0010) trying to solve the following JavaScript problem:
Given a non-negative integer, return an array containing a list of independent digits in reverse order.
Example:
348597 => The correct solution should be [7,9,5,8,4,3]
The function below apparently is incorrect as it returns ["7", "9", "5", "8", "4", "3"] - correct order but with quotes. How could I modify it so that it returns [7,9,5,8,4,3]?
function digitize(n) {
var initialArray = (""+n).split('');
var reversedArray = [];
for (var i = initialArray.length - 1; i >= 0; i--) {
reversedArray[i] = initialArray.shift();
}
return reversedArray;
}
"One-line" solution:
var num = 348597,
arr = String(num).split("").reverse().map(Number);
console.log(arr); // [7, 9, 5, 8, 4, 3]
String(num) : The String global object acts as a constructor for strings and "converts" the given number into string(in this case)
The Array.reverse(): method reverses an array in place
The Array.map(): method creates and returns a new array calling a provided function on every array element
add parseInt to convert from string to number, since when you split you turn every integer into a string
function digitize(n) {
var initialArray = (""+n).split('');
var reversedArray = [];
for (var i = initialArray.length - 1; i >= 0; i--) {
reversedArray[i] = parseInt(initialArray.shift(),10);
}
return reversedArray;
}
console.log(digitize(348597));
Even better, reduce it to two lines:
function digitize(num) {
return num.toString().split('').reverse().map(Number);
}
The final map call applies a function to each element in the array (in this case the function converts a string to an object) - everything else simply converts the number to a string, splits the string to an array and reverses it.
Traditionally, parseInt would be used in the map call, but this gives rise to strange behaviour.
Just split and reverse
var num = 348597,
arr = num.toString().split("").reverse().map(Number);
document.write('<pre>' + JSON.stringify(arr, 0, 4) + '</pre>');
It is a simplified version of many other solutions that you can see, to deep understand how it works.
function digitize(n) {
let correctArr = [];
let arrOfNumbers = n.toString().split('');
let arrOfNumbersLength = arrOfNumbers.length;
for (let i = 0; i < arrOfNumbersLength; i++) {
let x = arrOfNumbers.pop();
correctArr.push(+x);
}
return correctArr;
}
console.log(digitize(348597));
If you care about performance, here is the one.
var num = 348597;
var digits = num + '';
var result = [];
for (var i = 0, length = digits.length; i < length; i++) {
result[length - 1 - i] = +digits[i];
}
console.log(result);
For beginners who may want to see a clear format on how to solve this via plain English, this may help to understand it:
function reverseNumber(num){
num = num + '';
let reversedText = num.split('').reverse().join('');
let reversedNumber = parseInt(reversedText, 10);
console.log("reversed number: ", reversedNumber);
return reversedNumber;
}
console.log(reverseNumber(12345));
A simpler way to solve this is below.
function digitize(n) {
numbers = n.toString()//convert n to a string
arrayNum = numbers.split('') //split the string and make an array
arrayRev =arrayNum.reverse()//reverse the new array made.
newArr = arrayRev.map(Number) // The Number constructor contains constants and methods for working with numbers. Values of other types can be converted to numbers using the Number() function.
return newArr;
}
Refactored
function digitize(n) {
return n.toString().split('').reverse().map(Number)
}

Get a random item from a JavaScript array [duplicate]

This question already has answers here:
Getting a random value from a JavaScript array
(28 answers)
Closed 7 years ago.
var items = Array(523, 3452, 334, 31, ..., 5346);
How do I get random item from items?
var item = items[Math.floor(Math.random()*items.length)];
1. solution: define Array prototype
Array.prototype.random = function () {
return this[Math.floor((Math.random()*this.length))];
}
that will work on inline arrays
[2,3,5].random()
and of course predefined arrays
var list = [2,3,5]
list.random()
2. solution: define custom function that accepts list and returns element
function get_random (list) {
return list[Math.floor((Math.random()*list.length))];
}
get_random([2,3,5])
Use underscore (or loDash :)):
var randomArray = [
'#cc0000','#00cc00', '#0000cc'
];
// use _.sample
var randomElement = _.sample(randomArray);
// manually use _.random
var randomElement = randomArray[_.random(randomArray.length-1)];
Or to shuffle an entire array:
// use underscore's shuffle function
var firstRandomElement = _.shuffle(randomArray)[0];
If you really must use jQuery to solve this problem (NB: you shouldn't):
(function($) {
$.rand = function(arg) {
if ($.isArray(arg)) {
return arg[$.rand(arg.length)];
} else if (typeof arg === "number") {
return Math.floor(Math.random() * arg);
} else {
return 4; // chosen by fair dice roll
}
};
})(jQuery);
var items = [523, 3452, 334, 31, ..., 5346];
var item = jQuery.rand(items);
This plugin will return a random element if given an array, or a value from [0 .. n) given a number, or given anything else, a guaranteed random value!
For extra fun, the array return is generated by calling the function recursively based on the array's length :)
Working demo at http://jsfiddle.net/2eyQX/
Here's yet another way:
function rand(items) {
// "~~" for a closest "int"
return items[~~(items.length * Math.random())];
}
Or as recommended below by #1248177:
function rand(items) {
// "|" for a kinda "int div"
return items[items.length * Math.random() | 0];
}
var random = items[Math.floor(Math.random()*items.length)]
jQuery is JavaScript! It's just a JavaScript framework. So to find a random item, just use plain old JavaScript, for example,
var randomItem = items[Math.floor(Math.random()*items.length)]
// 1. Random shuffle items
items.sort(function() {return 0.5 - Math.random()})
// 2. Get first item
var item = items[0]
Shorter:
var item = items.sort(function() {return 0.5 - Math.random()})[0];
Even shoter (by José dB.):
let item = items.sort(() => 0.5 - Math.random())[0];
var rndval=items[Math.floor(Math.random()*items.length)];
var items = Array(523,3452,334,31,...5346);
function rand(min, max) {
var offset = min;
var range = (max - min) + 1;
var randomNumber = Math.floor( Math.random() * range) + offset;
return randomNumber;
}
randomNumber = rand(0, items.length - 1);
randomItem = items[randomNumber];
credit:
Javascript Function: Random Number Generator
If you are using node.js, you can use unique-random-array. It simply picks something random from an array.
An alternate way would be to add a method to the Array prototype:
Array.prototype.random = function (length) {
return this[Math.floor((Math.random()*length))];
}
var teams = ['patriots', 'colts', 'jets', 'texans', 'ravens', 'broncos']
var chosen_team = teams.random(teams.length)
alert(chosen_team)
const ArrayRandomModule = {
// get random item from array
random: function (array) {
return array[Math.random() * array.length | 0];
},
// [mutate]: extract from given array a random item
pick: function (array, i) {
return array.splice(i >= 0 ? i : Math.random() * array.length | 0, 1)[0];
},
// [mutate]: shuffle the given array
shuffle: function (array) {
for (var i = array.length; i > 0; --i)
array.push(array.splice(Math.random() * i | 0, 1)[0]);
return array;
}
}

Fastest way to duplicate an array in JavaScript - slice vs. 'for' loop

In order to duplicate an array in JavaScript: Which of the following is faster to use?
Slice method
var dup_array = original_array.slice();
For loop
for(var i = 0, len = original_array.length; i < len; ++i)
dup_array[i] = original_array[i];
I know both ways do only a shallow copy: if original_array contains references to objects, objects won't be cloned, but only the references will be copied, and therefore both arrays will have references to the same objects.
But this is not the point of this question.
I'm asking only about speed.
There are at least 6 (!) ways to clone an array:
loop
slice
Array.from()
concat
spread syntax (FASTEST)
map A.map(function(e){return e;});
There has been a huuuge BENCHMARKS thread, providing following information:
for blink browsers slice() is the fastest method, concat() is a bit slower, and while loop is 2.4x slower.
for other browsers while loop is the fastest method, since those browsers don't have internal optimizations for slice and concat.
This remains true in Jul 2016.
Below are simple scripts that you can copy-paste into your browser's console and run several times to see the picture. They output milliseconds, lower is better.
while loop
n = 1000*1000;
start = + new Date();
a = Array(n);
b = Array(n);
i = a.length;
while(i--) b[i] = a[i];
console.log(new Date() - start);
slice
n = 1000*1000;
start = + new Date();
a = Array(n);
b = a.slice();
console.log(new Date() - start);
Please note that these methods will clone the Array object itself, array contents however are copied by reference and are not deep cloned.
origAr == clonedArr //returns false
origAr[0] == clonedArr[0] //returns true
Technically slice is the fastest way. However, it is even faster if you add the 0 begin index.
myArray.slice(0);
is faster than
myArray.slice();
https://jsben.ch/F0SZ3
what about es6 way?
arr2 = [...arr1];
Easiest way to deep clone Array or Object:
var dup_array = JSON.parse(JSON.stringify(original_array))
🏁 Fastest Way to Clone an Array
I made this very plain utility function to test the time that it takes to clone an array. It is not 100% reliable however it can give you a bulk idea as for how long it takes to clone an existing array:
function clone(fn) {
const arr = [...Array(1000000)];
console.time('timer');
fn(arr);
console.timeEnd('timer');
}
And tested different approach:
1) 5.79ms -> clone(arr => Object.values(arr));
2) 7.23ms -> clone(arr => [].concat(arr));
3) 9.13ms -> clone(arr => arr.slice());
4) 24.04ms -> clone(arr => { const a = []; for (let val of arr) { a.push(val); } return a; });
5) 30.02ms -> clone(arr => [...arr]);
6) 39.72ms -> clone(arr => JSON.parse(JSON.stringify(arr)));
7) 99.80ms -> clone(arr => arr.map(i => i));
8) 259.29ms -> clone(arr => Object.assign([], arr));
9) Maximum call stack size exceeded -> clone(arr => Array.of(...arr));
UPDATE:
Tests were made back in 2018, so today most likely you'll get different result with current browsers.
Out of all of those, the only way to deep clone an array is by using JSON.parse(JSON.stringify(arr)).
That said, do not use the above if your array might include functions as it will return null.Thank you #GilEpshtain for this update.
var cloned_array = [].concat(target_array);
I put together a quick demo: http://jsbin.com/agugo3/edit
My results on Internet Explorer 8 are 156, 782, and 750, which would indicate slice is much faster in this case.
a.map(e => e) is another alternative for this job. As of today .map() is very fast (almost as fast as .slice(0)) in Firefox, but not in Chrome.
On the other hand, if an array is multi-dimensional, since arrays are objects and objects are reference types, none of the slice or concat methods will be a cure... So one proper way of cloning an array is an invention of Array.prototype.clone() as follows.
Array.prototype.clone = function(){
return this.map(e => Array.isArray(e) ? e.clone() : e);
};
var arr = [ 1, 2, 3, 4, [ 1, 2, [ 1, 2, 3 ], 4 , 5], 6 ],
brr = arr.clone();
brr[4][2][1] = "two";
console.log(JSON.stringify(arr));
console.log(JSON.stringify(brr));
Fastest way to clone an Array of Objects will be using spread operator
var clonedArray=[...originalArray]
or
var clonedArray = originalArray.slice(0); //with 0 index it's little bit faster than normal slice()
but the objects inside that cloned array will still pointing at the old memory location. hence change to clonedArray objects will also change the orignalArray. So
var clonedArray = originalArray.map(({...ele}) => {return ele})
this will not only create new array but also the objects will be cloned to.
disclaimer if you are working with nested object in that case spread operator will work as SHALLOW CLONE. At that point better to use
var clonedArray=JSON.parse(JSON.stringify(originalArray));
Take a look at: link. It's not about speed, but comfort. Besides as you can see you can only use slice(0) on primitive types.
To make an independent copy of an array rather than a copy of the refence to it, you can use the array slice method.
Example:
To make an independent copy of an array rather than a copy of the refence to it, you can use the array slice method.
var oldArray = ["mip", "map", "mop"];
var newArray = oldArray.slice();
To copy or clone an object :
function cloneObject(source) {
for (i in source) {
if (typeof source[i] == 'source') {
this[i] = new cloneObject(source[i]);
}
else{
this[i] = source[i];
}
}
}
var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
var obj2= new cloneObject(obj1);
Source: link
ECMAScript 2015 way with the Spread operator:
Basic examples:
var copyOfOldArray = [...oldArray]
var twoArraysBecomeOne = [...firstArray, ..seccondArray]
Try in the browser console:
var oldArray = [1, 2, 3]
var copyOfOldArray = [...oldArray]
console.log(oldArray)
console.log(copyOfOldArray)
var firstArray = [5, 6, 7]
var seccondArray = ["a", "b", "c"]
var twoArraysBecomOne = [...firstArray, ...seccondArray]
console.log(twoArraysBecomOne);
References
6 Great Uses of the Spread Operator
Spread syntax
As #Dan said "This answer becomes outdated fast. Use benchmarks to check the actual situation", there is one specific answer from jsperf that has not had an answer for itself: while:
var i = a.length;
while(i--) { b[i] = a[i]; }
had 960,589 ops/sec with the runnerup a.concat() at 578,129 ops/sec, which is 60%.
This is the lastest Firefox (40) 64 bit.
#aleclarson created a new, more reliable benchmark.
Benchmark time!
function log(data) {
document.getElementById("log").textContent += data + "\n";
}
benchmark = (() => {
time_function = function(ms, f, num) {
var z = 0;
var t = new Date().getTime();
for (z = 0;
((new Date().getTime() - t) < ms); z++)
f(num);
return (z)
}
function clone1(arr) {
return arr.slice(0);
}
function clone2(arr) {
return [...arr]
}
function clone3(arr) {
return [].concat(arr);
}
Array.prototype.clone = function() {
return this.map(e => Array.isArray(e) ? e.clone() : e);
};
function clone4(arr) {
return arr.clone();
}
function benchmark() {
function compare(a, b) {
if (a[1] > b[1]) {
return -1;
}
if (a[1] < b[1]) {
return 1;
}
return 0;
}
funcs = [clone1, clone2, clone3, clone4];
results = [];
funcs.forEach((ff) => {
console.log("Benchmarking: " + ff.name);
var s = time_function(2500, ff, Array(1024));
results.push([ff, s]);
console.log("Score: " + s);
})
return results.sort(compare);
}
return benchmark;
})()
log("Starting benchmark...\n");
res = benchmark();
console.log("Winner: " + res[0][0].name + " !!!");
count = 1;
res.forEach((r) => {
log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");
});
log("\nWinner code:\n");
log(res[0][0].toString());
<textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>
The benchmark will run for 10s since you click the button.
My results:
Chrome (V8 engine):
1. clone1 score: 100% *winner* (4110764)
2. clone3 score: 74.32% speed of winner. (3055225)
3. clone2 score: 30.75% speed of winner. (1264182)
4. clone4 score: 21.96% speed of winner. (902929)
Firefox (SpiderMonkey Engine):
1. clone1 score: 100% *winner* (8448353)
2. clone3 score: 16.44% speed of winner. (1389241)
3. clone4 score: 5.69% speed of winner. (481162)
4. clone2 score: 2.27% speed of winner. (192433)
Winner code:
function clone1(arr) {
return arr.slice(0);
}
Winner engine:
SpiderMonkey (Mozilla/Firefox)
It depends on the browser. If you look in the blog post Array.prototype.slice vs manual array creation, there is a rough guide to performance of each:
Results:
There is a much cleaner solution:
var srcArray = [1, 2, 3];
var clonedArray = srcArray.length === 1 ? [srcArray[0]] : Array.apply(this, srcArray);
The length check is required, because the Array constructor behaves differently when it is called with exactly one argument.
Remember .slice() won't work for two-dimensional arrays. You'll need a function like this:
function copy(array) {
return array.map(function(arr) {
return arr.slice();
});
}
It depends on the length of the array. If the array length is <= 1,000,000, the slice and concat methods are taking approximately the same time. But when you give a wider range, the concat method wins.
For example, try this code:
var original_array = [];
for(var i = 0; i < 10000000; i ++) {
original_array.push( Math.floor(Math.random() * 1000000 + 1));
}
function a1() {
var dup = [];
var start = Date.now();
dup = original_array.slice();
var end = Date.now();
console.log('slice method takes ' + (end - start) + ' ms');
}
function a2() {
var dup = [];
var start = Date.now();
dup = original_array.concat([]);
var end = Date.now();
console.log('concat method takes ' + (end - start) + ' ms');
}
function a3() {
var dup = [];
var start = Date.now();
for(var i = 0; i < original_array.length; i ++) {
dup.push(original_array[i]);
}
var end = Date.now();
console.log('for loop with push method takes ' + (end - start) + ' ms');
}
function a4() {
var dup = [];
var start = Date.now();
for(var i = 0; i < original_array.length; i ++) {
dup[i] = original_array[i];
}
var end = Date.now();
console.log('for loop with = method takes ' + (end - start) + ' ms');
}
function a5() {
var dup = new Array(original_array.length)
var start = Date.now();
for(var i = 0; i < original_array.length; i ++) {
dup.push(original_array[i]);
}
var end = Date.now();
console.log('for loop with = method and array constructor takes ' + (end - start) + ' ms');
}
a1();
a2();
a3();
a4();
a5();
If you set the length of original_array to 1,000,000, the slice method and concat method are taking approximately the same time (3-4 ms, depending on the random numbers).
If you set the length of original_array to 10,000,000, then the slice method takes over 60 ms and the concat method takes over 20 ms.
In ES6, you can simply utilize the Spread syntax.
Example:
let arr = ['a', 'b', 'c'];
let arr2 = [...arr];
Please note that the spread operator generates a completely new array, so modifying one won't affect the other.
Example:
arr2.push('d') // becomes ['a', 'b', 'c', 'd']
console.log(arr) // while arr retains its values ['a', 'b', 'c']
A simple solution:
original = [1,2,3]
cloned = original.map(x=>x)
const arr = ['1', '2', '3'];
// Old way
const cloneArr = arr.slice();
// ES6 way
const cloneArrES6 = [...arr];
// But problem with 3rd approach is that if you are using muti-dimensional
// array, then only first level is copied
const nums = [
[1, 2],
[10],
];
const cloneNums = [...nums];
// Let's change the first item in the first nested item in our cloned array.
cloneNums[0][0] = '8';
console.log(cloneNums);
// [ [ '8', 2 ], [ 10 ], [ 300 ] ]
// NOOooo, the original is also affected
console.log(nums);
// [ [ '8', 2 ], [ 10 ], [ 300 ] ]
So, in order to avoid these scenarios to happen, use
const arr = ['1', '2', '3'];
const cloneArr = Array.from(arr);
There were several ways to clone an array. Basically, Cloning was categorized in two ways:
Shallow copy
Deep copy
Shallow copies only cover the 1st level of the array and the rest are
referenced. If you want a true copy of nested elements in the arrays, you’ll need a
deep clone.
Example :
const arr1 = [1,2,3,4,5,6,7]
// Normal Array (shallow copy is enough)
const arr2 = [1,2,3,[4],[[5]],6,7]
// Nested Array (Deep copy required)
Approach 1 : Using (...)Spread Operator (Shallow copy enough)
const newArray = [...arr1] // [1,2,3,4,5,6,7]
Approach 2 : Using Array builtIn Slice method (Deep copy)
const newArray = arr1.slice() // [1,2,3,4,5,6,7]
Approach 3 : Using Array builtIn Concat method (Deep a copy)
const newArray = [].concat(arr1) // [1,2,3,4,5,6,7]
Approach 4 : Using JSON.stringify/parse. (Deep a copy & fastest)
const newArray = JSON.parse(JSON.stringify(arr2));) // [1,2,3,[4],[[5]],6,7]
Approach 5: Using own recursive function or using loadash's __.cloneDeep method. (Deep copy)
Fast ways to duplicate an array in JavaScript in Order:
#1: array1copy = [...array1];
#2: array1copy = array1.slice(0);
#3: array1copy = array1.slice();
If your array objects contain some JSON-non-serializable content (functions, Number.POSITIVE_INFINITY, etc.) better to use
array1copy = JSON.parse(JSON.stringify(array1))
You can follow this code. Immutable way array clone. This is the perfect way to array cloning
const array = [1, 2, 3, 4]
const newArray = [...array]
newArray.push(6)
console.log(array)
console.log(newArray)
If you want a REAL cloned object/array in JS with cloned references of all attributes and sub-objects:
export function clone(arr) {
return JSON.parse(JSON.stringify(arr))
}
ALL other operations do not create clones, because they just change the base address of the root element, not of the included objects.
Except you traverse recursive through the object-tree.
For a simple copy, these are OK. For storage address relevant operations I suggest (and in most all other cases, because this is fast!) to type convert into string and back in a complete new object.
If you are taking about slice it is used to copy elements from an array and create a clone with same no. of elements or less no. of elements.
var arr = [1, 2, 3 , 4, 5];
function slc() {
var sliced = arr.slice(0, 5);
// arr.slice(position to start copying master array , no. of items in new array)
console.log(sliced);
}
slc(arr);

Categories