I have two json files, list1.json and list2.json and I managed to concat them, but I have two roles:
Resulting list should contain only 10 random items from list1.json, all the items from list2.json, and then I should display them in random order on the page.
How can I do that?
You can use lodash for this task.
_.sampleSize(list1.json, 10) will give you ten random items,
then _.concat(_.sampleSize(list1.json, 10), list2.json) will give you the desired result.
After you have a list containing the desired items, you can randomize its order by using the _.shuffle function.
You can read a bit more here:
https://lodash.com/docs#sampleSize and https://lodash.com/docs#concat
Off course both these functions work on JavaScript Arrays and not files, you would have to read/require these files and parse them first.
Solution with plain javascript (but I suggest too going with underscore or lodash as Gilad Artzi says).
function array_random_idx(arr) {
var idx = parseInt(Math.random() * arr.length);
return idx;
}
function remove_random(arr) {
var idx = array_random_idx(arr);
return arr.splice(idx, 1)[0];
}
function array_shuffle(a) {
var j, x, i;
for (i = a.length; i; i -= 1) {
j = Math.floor(Math.random() * i);
x = a[i - 1];
a[i - 1] = a[j];
a[j] = x;
}
}
var result1 = []
for (var i = 0; i < 10; i++) {
var elem = remove_random(list1.json);
result1.push(elem);
}
var result = result1.concat(list2.json);
array_shuffle(result);
console.log(result);
Related
I am attempting to create a matrix of 3 arrays with 10 elements in each array. Each element should be a random number between 1 and 10. I wanted to use a single function to generate each of the arrays, and used this:
var array1 = [];
var array2 = [];
var array3 = [];
var tempName;
function fcnArrayGenerate(){
let i = 1;
while (i < 4){
tempName = "array" + i;
let j = 0;
while (j < 10){
tempName.push((Math.floor(Math.random() * 10) + 1));
j++;
}
i++;
}
console.log(array1);
console.log(array2);
console.log(array3);
}
However, when I run the function, I receive an error stating that "tempName.push is not a function." Any assistance on how to correct this would be appreciated. Thank you.
Instead of using three variables for three different arrays, you can use a single multidimensional array to store those three arrays.
let array = [[], [], []];
function fcnArrayGenerate() {
let i = 0;
while (i <= 2) {
let j = 0;
while (j < 10) {
array[i].push(Math.floor(Math.random() * 10) + 1);
j++;
}
i++;
}
}
// call the function
fcnArrayGenerate();
// now print the arrays as tables
console.table(array);
console.table(array[0]);
console.table(array[1]);
console.table(array[2]);
Note: console.table() allows you to print out arrays and objects to the console in tabular form.
If you want to push into tempName you have to initialise it with an empty array first. Right now it’s undefined. Hence you’re seeing the error as you can’t push something to undefined
Do this:
var tempName = []
To make variable names incremental, you can pass them as objects.
var data = {
array1: [],
array2: [],
array3: []
}
function fcnArrayGenerate(){
let i = 1;
while (i < 4){
let j = 0;
while (j < 10){
data['array' + i].push((Math.floor(Math.random() * 10) + 1));
j++;
}
i++;
}
console.log(data.array1);
console.log(data.array2);
console.log(data.array3);
}
fcnArrayGenerate();
I need help with writing some code that will create a random number from an array of 12 numbers and print it 9 times without dupes. This has been tough for me to accomplish. Any ideas?
var nums = [1,2,3,4,5,6,7,8,9,10,11,12];
var gen_nums = [];
function in_array(array, el) {
for(var i = 0 ; i < array.length; i++)
if(array[i] == el) return true;
return false;
}
function get_rand(array) {
var rand = array[Math.floor(Math.random()*array.length)];
if(!in_array(gen_nums, rand)) {
gen_nums.push(rand);
return rand;
}
return get_rand(array);
}
for(var i = 0; i < 9; i++) {
console.log(get_rand(nums));
}
The most effective and efficient way to do this is to shuffle your numbers then print the first nine of them. Use a good shuffle algorithm.What Thilo suggested will give you poor results. See here.
Edit
Here's a brief Knuth Shuffle algorithm example:
void shuffle(vector<int> nums)
{
for (int i = nums.size()-1; i >= 0; i--)
{
// this line is really shorthand, but gets the point across, I hope.
swap(nums[i],nums[rand()%i]);
}
}
Try this once:
//Here o is the array;
var testArr = [6, 7, 12, 15, 17, 20, 21];
shuffle = function(o){ //v1.0
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
shuffle(testArr);
This is relatively simple to do, the theory behind it is creating another array which keeps track of which elements of the array you have used.
var tempArray = new Array(12),i,r;
for (i=0;i<9;i++)
{
r = Math.floor(Math.random()*12); // Get a random index
if (tempArray[r] === undefined) // If the index hasn't been used yet
{
document.write(numberArray[r]); // Display it
tempArray[r] = true; // Flag it as have been used
}
else // Otherwise
{
i--; // Try again
}
}
Other methods include shuffling the array, removing used elements from the array, or moving used elements to the end of the array.
If I understand you correctly, you want to shuffle your array.
Loop a couple of times (length of array should do), and in every iteration, get two random array indexes and swap the two elements there. (Update: if you are really serious about this, this may not be the best algorithm).
You can then print the first nine array elements, which will be in random order and not repeat.
Here is a generic way of getting random numbers between min and max without duplicates:
function inArray(arr, el) {
for(var i = 0 ; i < arr.length; i++)
if(arr[i] == el) return true;
return false;
}
function getRandomIntNoDuplicates(min, max, DuplicateArr) {
var RandomInt = Math.floor(Math.random() * (max - min + 1)) + min;
if (DuplicateArr.length > (max-min) ) return false; // break endless recursion
if(!inArray(DuplicateArr, RandomInt)) {
DuplicateArr.push(RandomInt);
return RandomInt;
}
return getRandomIntNoDuplicates(min, max, DuplicateArr); //recurse
}
call with:
var duplicates =[];
for (var i = 1; i <= 6 ; i++) {
console.log(getRandomIntNoDuplicates(1,10,duplicates));
}
const nums = [1,2,3,4,5,6,7,8,9,10,11,12];
for(var i = 1 ; i < 10; i++){
result = nums[Math.floor(Math.random()*nums.length)];
const index = nums.indexOf(result);
nums.splice(index, 1);
console.log(i+' - '+result);
}
This question already has answers here:
How to randomize (shuffle) a JavaScript array?
(69 answers)
Closed 6 years ago.
I have an array
var array = ["what","is","going","on"];
I know it's possible to access and list these elements with a standard for loop like so:
for (i = 0; i <= array.length; i++) {
console.log(array[i]);
}
But I want to know if there's a way to list these elements in a random order. I suspect that I have to use some variation of Math. but I don't have enough experience to decide which to use for sure. Thanks in advance!
You should first shuffle the array and then read one by one. An array method like Array.prototype.shuffle() might come handy.
Array.prototype.shuffle = function(){
var i = this.length,
j,
tmp;
while (i > 1) {
j = Math.floor(Math.random()*i--);
tmp = this[i];
this[i] = this[j];
this[j] = tmp;
}
return this;
};
var arr = [1,2,3,4,5].shuffle();
for(var i = 0; i < arr.length; i++) console.log(arr[i]);
Statistically speaking, this will definitely work. It just may take until the heat-death of the universe to complete.
var array = ["What", "am", "I", "doing", "with", "my", "life"];
var processed = [];
function randomAccess() {
if (processed.length === array.length) {
console.log('Done!');
return;
}
var index = Math.floor(Math.random() * array.length);
if (processed.indexOf(index) === -1) {
// Make sure we haven't processed this one before
console.log('array[' + index + ']:', array[index]);
processed.push(index);
}
// Prevent locking up the browser
setTimeout(randomAccess, 0);
}
randomAccess();
Please don't use this in production code. Theoretically, it may never complete.
Yes, you can introduce a second array to log the indices you have randomly returned - in order not to return the same index more than once.
Working example:
var myArray = ['what','is','going','on'];
var returnedIndices = [];
for (i = 0; i < myArray.length; i++) {
var randomIndex = Math.floor(Math.random() * myArray.length);
if (returnedIndices.indexOf(randomIndex) !== -1) {
i--;
continue;
}
else {
returnedIndices[i] = randomIndex;
console.log(myArray[randomIndex]);
}
}
console.log(array[Math.floor(Math.random() * (array.length - 1))]);
I need help with writing some code that will create a random number from an array of 12 numbers and print it 9 times without dupes. This has been tough for me to accomplish. Any ideas?
var nums = [1,2,3,4,5,6,7,8,9,10,11,12];
var gen_nums = [];
function in_array(array, el) {
for(var i = 0 ; i < array.length; i++)
if(array[i] == el) return true;
return false;
}
function get_rand(array) {
var rand = array[Math.floor(Math.random()*array.length)];
if(!in_array(gen_nums, rand)) {
gen_nums.push(rand);
return rand;
}
return get_rand(array);
}
for(var i = 0; i < 9; i++) {
console.log(get_rand(nums));
}
The most effective and efficient way to do this is to shuffle your numbers then print the first nine of them. Use a good shuffle algorithm.What Thilo suggested will give you poor results. See here.
Edit
Here's a brief Knuth Shuffle algorithm example:
void shuffle(vector<int> nums)
{
for (int i = nums.size()-1; i >= 0; i--)
{
// this line is really shorthand, but gets the point across, I hope.
swap(nums[i],nums[rand()%i]);
}
}
Try this once:
//Here o is the array;
var testArr = [6, 7, 12, 15, 17, 20, 21];
shuffle = function(o){ //v1.0
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
shuffle(testArr);
This is relatively simple to do, the theory behind it is creating another array which keeps track of which elements of the array you have used.
var tempArray = new Array(12),i,r;
for (i=0;i<9;i++)
{
r = Math.floor(Math.random()*12); // Get a random index
if (tempArray[r] === undefined) // If the index hasn't been used yet
{
document.write(numberArray[r]); // Display it
tempArray[r] = true; // Flag it as have been used
}
else // Otherwise
{
i--; // Try again
}
}
Other methods include shuffling the array, removing used elements from the array, or moving used elements to the end of the array.
If I understand you correctly, you want to shuffle your array.
Loop a couple of times (length of array should do), and in every iteration, get two random array indexes and swap the two elements there. (Update: if you are really serious about this, this may not be the best algorithm).
You can then print the first nine array elements, which will be in random order and not repeat.
Here is a generic way of getting random numbers between min and max without duplicates:
function inArray(arr, el) {
for(var i = 0 ; i < arr.length; i++)
if(arr[i] == el) return true;
return false;
}
function getRandomIntNoDuplicates(min, max, DuplicateArr) {
var RandomInt = Math.floor(Math.random() * (max - min + 1)) + min;
if (DuplicateArr.length > (max-min) ) return false; // break endless recursion
if(!inArray(DuplicateArr, RandomInt)) {
DuplicateArr.push(RandomInt);
return RandomInt;
}
return getRandomIntNoDuplicates(min, max, DuplicateArr); //recurse
}
call with:
var duplicates =[];
for (var i = 1; i <= 6 ; i++) {
console.log(getRandomIntNoDuplicates(1,10,duplicates));
}
const nums = [1,2,3,4,5,6,7,8,9,10,11,12];
for(var i = 1 ; i < 10; i++){
result = nums[Math.floor(Math.random()*nums.length)];
const index = nums.indexOf(result);
nums.splice(index, 1);
console.log(i+' - '+result);
}
I have a comma separated string, out of which I need to create a new string which contains a random order of the items in the original string, while making sure there are no recurrences.
For example:
Running 1,2,3,1,3 will give 2,3,1 and another time 3,1,2, and so on.
I have a code which picks a random item in the original string, and then iterates over the new string to see if it does not exist already. If it does not exist - the item is inserted.
However, I have a feeling this can be improved (in C# I would have used a hashtable, instead of iterating every time on the new array). One improvement can be removing the item we inserted from the original array, in order to prevent cases where the random number will give us the same result, for example.
I'd be happy if you could suggest improvements to the code below.
originalArray = originalList.split(',');
for (var j = 0; j < originalArray.length; j++) {
var iPlaceInOriginalArray = Math.round(Math.random() * (originalArray.length - 1));
var bAlreadyExists = false;
for (var i = 0; i < newArray.length; i++) {
if (newArray[i].toString() == originalArray[iPlaceInOriginalArray].toString()) {
bAlreadyExists = true;
break;
}
}
if (!bAlreadyExists)
newArray.push(originalArray[iPlaceInOriginalArray]);
}
Thanks!
You can still use a 'hash' in javascript to remove duplicates. Only in JS they're called objects:
function removeDuplicates(arr) {
var hash = {};
for (var i=0,l=arr.length;i<l;i++) {
hash[arr[i]] = 1;
}
// now extract hash keys... ahem...
// I mean object members:
arr = [];
for (var n in hash) {
arr.push(n);
}
return arr;
}
Oh, and the select random from an array thing. If it's ok to destroy the original array (which in your case it is) then use splice:
function randInt (n) {return Math.floor(Math.random()*n)}
function shuffle (arr) {
var out = [];
while (arr.length) {
out.push(
arr.splice(
randInt(arr.length),1 ));
}
return out;
}
// So:
newArray = shuffle(
removeDuplicates(
string.split(',') ));
// If you sort the first array, it is quicker to skip duplicates, and you can splice each unique item into its random position as you build the new array.
var s= 'Function,String,Object,String,Array,Date,Error,String,String,'+
'Math,Number,RegExp,Group,Collection,Timelog,Color,String';
var A1= s.split(',').sort(), A2= [], tem;
while(A1.length){
tem= A1.shift();
while(A1[0]== tem) tem= A1.shift();
if(tem) A2.splice(Math.floor(Math.random()*A2.length), 0, tem);
}
alert(A2.join(', '))
With your solution, you are not guaranteed not to pick same number several times, thus leaving some others of them never being picked. If the number of elements is not big (up to 100), deleting items from the source array will give the best result.
Edit
originalArray = originalList.split(',');
for (var j = 0; j < originalArray.length; j++) {
var iPlaceInOriginalArray = Math.round(Math.random() * (originalArray.length - 1 - j));
var bAlreadyExists = false;
for (var i = 0; i < newArray.length; i++) {
if (newArray[i].toString() == originalArray[iPlaceInOriginalArray].toString()) {
bAlreadyExists = true;
break;
}
}
var tmp = originalArray[originalArray.length - 1 - j];
originalArray[originalArray.Length - 1 - j] = originalArray[iPlaceInOriginalArray];
originalArray[iPlaceInOriginalArray] = tmp;
if (!bAlreadyExists)
newArray.push(originalArray[iPlaceInOriginalArray]);
}