Taking one array and randomizing it into another array - javascript

I have two arrays (representing a deck of cards), one filled with the values 1-52, and another filled with nothing. I want to take the position randomly from the first array and take that object and put it into the next spot available in the randomized array. I have this so far:
var shufdeck = new Array();
while(sufdeck.length < 52)
{
i = Math.floor(Math.random()*52);
//shufdeck[0] = deck[i] etc.
}
I'm not sure if I should be using splice or something else to take it out of the first array and put it into the second. If possible shufdeck[] should be filled and deck[] would be empty.
How can I shuffle an array?

Yes, you should splice out the chosen card, so:
var shuffledDeck = [];
while (deck.length) {
shuffledDeck.push(deck.splice(Math.random()*deck.length | 0, 1)[0]);
}
or to be a little more efficient:
var i = deck.length;
while (i) {
shuffledDeck.push(deck.splice(Math.random()*i-- | 0, 1)[0]);
}
Note that this will destroy deck. If you don't want that, copy it first:
var deckToShuffle = deck.slice();

Related

How to sort pushed array by id?

I have two arrays. First one which comes from response is divided by pagination. When i remove items from second array, they should be placed back sorted by id in first array, instead they go to bottom of array and i have to scroll down to find certain element. This is my code for pushing elements from array vm.feeds to vm.rationList:
function addAll() {
var mList = JSON.parse(JSON.stringify(vm.feeds))
for (var i = 0; i < mList.length; i++) {
mList[i].is_selected = false;
vm.rationList.push(mList[i]);
}
vm.feeds = [];
vm.rationListSafe = vm.rationList;
if(vm.feeds.length == 0){
vm.currentPageMaster++;
vm.isPage = true;
vm.disableScroll = true;
getFeedsByTeam(vm.selectedTeam);
}
}
Second part is how i remove elements from array vm.rationList and push them back to first array - vm.feeds:
function removeAll() {
for (var i = 0; i < vm.rationList.length; i++) {
vm.feeds.push(vm.rationList[i])
}
vm.rationList = []
}
In removeAll() i have to add additional check which will sort them by ID on push. Any idea for this?
The Array.push method add item to the end of your list.
To put an element at a given position in an array, you may prefer using Array.splice.
First argument is the index, second is the number of items to delete (in your case, 0), and a third argument would be the item to add at the given index.
With that, you can replace the push in removeAll by
vm.feeds.splice(correctIndex, 0, vm.rationList[i]);
Question is : what is correctIndex ?
Well, for that, there might be many solutions depending on your architecture, but a simple one could be to loop on vm.feeds to find the first item with an id that is not lower than the one you want to add:
var correctIndex = 0;
for(var item of vm.feeds) {
if (item.id >= vm.rationList[i].id) {break;}
else {correctIndex++;}
}
vm.feeds.sort(function(a, b) {
return parseFloat(a.id) - parseFloat(b.id);
});
This is the solution I found and it works

Picking random values from array and creating new array

I have an array, and need to pick three random values from that array. These will the be put in a new array and I will be able to see the new array on my website. I also have to make sure that no value gets picked twice.
This is what I have so far:
var student = ["Hans","Ole","Nils","Olav","Per","Knut","Line","Pia"];
var velg = student[Math.floor(Math.random() * student.length)];
I'm thinking I should add an id to my HTML, so the new array will show on my website, but I'm not sure about the rest.
First sort it randomly and then get first three:
student
.sort(function(){
return Math.random() - 0.5;
})
.slice(0,3)
Since Math.random() returns random value between 0 and 1, while sort expects values to be positive or negative to determine order we, we need to subtract 0.5 to make those negatives possible.
You could try something like this in a loop
var students = ["Hans","Ole","Nils","Olav","Per","Knut","Line","Pia"];
var randomStudents = [];
for(var i = 0; i < 3; i++) {
var velg = student[Math.floor(Math.random() * students.length)];
randomStudents.push(velg);
}
Note that this can add duplicate students to the array. You should check if student is already in the array and try again.
Keyword for that would be recursion.
https://www.codecademy.com/courses/javascript-lesson-205/0/1

How to move 3 elements of array one by one in each of loop iterations?

I have an array [1,1,1,0] (any size of), the minimum length of array and number 1 is 3. I want to keep moving the value of 1s 1 element up so it could move to [0,1,1,1], then back to [1,1,1,0].
My loop sort of work in recursive mode, but I'm not sure how to reset the values, so after 4 loops, my entire array is filled with 0's.
More lengthily array would traverse as so:
Example:
[1,1,1,0,0,0]-> [0,1,1,1,0,0]-> [0,0,1,1,1,0]-> [0,0,0,1,1,1]->
[1,1,0,0,0,1]-> [1,1,1,0,0,0]-> [0,1,1,1,0,0]-> [0,0,1,1,1,0]->
And so on for ever...
Code:
function flip(images, active) {
var new_active = active;
setTimeout(function() {
active.reverse();
active[active.length] = 0;
active.reverse();
active.pop();
for(var i = 0; i < active.length; i++) {
alert(active[i]);
}
flip(images, active);
}, 5000);
}
Depending on which direction you want to do, I would suggest using shift() and push(), or pop() and unshift().
Basically, shift() and unshift() add or remove an element from the front of the array, and push() and pop() add or remove an element from the back of the array.
For the example you have given, you'll probably want to pop() off the end of the array and unshift() to the front:
function rotateArray(arr) {
var element = arr.pop();
arr.unshift(element);
}
// Repeat in loop, timeout, etc. as necessary
First pop(store it).So [abcd]->[abc] and you have stored d.
Reverse. So [abc]->[cba].
Add the popped element. So [cba]->[cbad]
Reverse. So [cbad]->[dabc].
I hope you wanted that?
See this too.
Upvote if it helped you. :(
var arr = [1, 1, 1, 0, 0, 0],
startIndex = arr.indexOf(1),
sliceLength = 3,
slice;
while(arr[arr.length - 1] === 0) {
// slice out the 1's (modifies the original array)
slice = arr.splice(startIndex, sliceLength);
// splice the 1's back in, one spot over
arr.splice.apply(arr, [++startIndex, 0].concat(slice));
console.log(arr);
}
http://jsfiddle.net/sn7ujb90/1/

Reordering an array in javascript

there are many questions/answers dealing with this topic. None match my specific case. Hopefully someone can help:
I have an array of indexes such as:
var indexes = [24, 48, 32, 7, 11];
And an array of objects that look similar to this:
var items = [{
name : "whatever",
selected : false,
loading : true,
progress : 55,
complete : false
},
{
name : "whatever 2",
selected : false,
loading : false,
progress : 100,
complete : true
}];
Each integer within the indexes array corresponds to the actual index of an object within the items array.
Lastly I have a variable which defines the new insert position within the items array:
var insertindex = ??
What I would like to do is to take all objects in the items array that have the indexes stored in the indexes array, remove them, then finally place them back, all next to each other at a specified index defined by the variable insertindex.
I have been trying to use splice() by copying the objects at each index to a temporary array, then removing them from the original array, then finally looping through this new temporary array and putting them back into the original items array at the new positions, but seems to be hitting a mental brick wall and cannot get it to work correctly.
To summarize, I simply want to take all objects from the items array that match an index defined in the indexes array, put them together and reinsert them at a predefined index, back into the items array.
To help with conceptual visualization. If you think of the app as a javascript file manager, allowing the reordering of multiple file selections which do not have to be adjacent. The indexes array defining the current selection and the items array defining the list of files. And finally the rearoderindex defines the new insert position that all selected files should move to.
EDIT: As was rightly suggested here is the code I am playing with right now:
function reorder(items, indexes, insertindex){
var offset = 0;
var itemscopy = items.slice(0); //make shallow copy of original array
var temparray = new Array(); // create temporary array to hold pulled out objects
//loop through selected indexes and copy each into temp array
for(var i=0, len=indexes.length; i<len; i++){
array[i] = itemscopy[self.cache.selecteditems[i]];
}
//remove all selected items from items array
for(var i=0, len=indexes.length; i<len; i++){
items.splice(indexes[i], 1);
}
//finally loop through new temp array and insert the items back into the items array at the specified index, increasing the index each iteration using the offset variable.
for(var i=0, len=temparray.length; i<len; i++){
items.splice((insertindex+offset), 0, array[i]);
offset++;
}
}
I'm aware this is pretty horrible and that looping three times should not be necessary. But I've been trying lots of different methods, some working when reordering in one direction, some in the other an mostly, not at all. I figured I would look to optimize the function later, once I have it working with accuracy.
I'm certain I must be doing something extremely stupid or completely overlooking something, but for the life of me I can't work out what right now.
If you don't care about order of indexes array, I'd suggest another short solution:
items.splice.apply(items, [insertIndex, 0].concat(indexes.sort(function(a, b) {
return a - b;
})).map(function(i, p) {
return p > 1 ? items.splice(i - p + 2, 1).pop() : i;
}));
DEMO: http://jsfiddle.net/T83fB/
To make it short I used Array.map() method, which is not supported by old IE browsers. However it is always easy to use a shim from MDN.
You can use the .splice() function to add elements to an array, as well as removing items from it. The general principle is:
Sort indexes into ascending numeric order
Iterate over indexes, removing the element at that index (adjusting for the number of removed items) and storing it in a removedItems array
Add the removedItems array back in at the required index
The code to do that would look something like this:
var removedItems = [];
// sort indexes
indexes.sort(function(a, b) {
if(a < b) return -1;
else if(b < a) return 1;
return 0;
});
for(var i = 0; i < indexes.length; i++) {
var index = indexes[i];
removedItems.push(items.splice(index - removedItems.length, 1));
}
var insertIndex = 1;
items.splice.apply(items, [insertIndex, 0].concat(removedItems));
Take a look at this jsFiddle demo.

Javascript Array not being filled properly

I'm having some trouble getting an array to be filled properly. I'm attempting to get a deck of cards to be loaded into an array and then shuffled which does work fine initially, however, after I do a check to see if there are enough cards left, the array does not load properly and everything more or less breaks.
Here's the relevant code. Any help would be greatly appreciated. Thanks!
var deck = {
//base deck before shuffle
baseDeck: ['d02', 'd03', 'd04', 'd05', 'd06', 'd07', 'd08', 'd09', 'd10', 'd11', 'd12', 'd13', 'd14', 'h02', 'h03', 'h04', 'h05', 'h06', 'h07', 'h08', 'h09', 'h10', 'h11', 'h12', 'h13', 'h14', 'c02', 'c03', 'c04', 'c05', 'c06', 'c07', 'c08', 'c09', 'c10', 'c11', 'c12', 'c13', 'c14', 's02', 's03', 's04', 's05', 's06', 's07', 's08', 's09', 's10', 's11', 's12', 's13', 's14'],
//Deck Shoe
shoe: [],
//pull deck #, return to shoe
shuffleDeck: function () {
this.shoe.length = 0;
this.shoe = this.baseDeck;
for (i = 0; i < this.shoe.length; i++) {
var randomPlace = Math.floor(Math.random() * 50) + 1;
var currentPlace = this.shoe[i];
this.shoe[i] = this.shoe[randomPlace];
this.shoe[randomPlace] = currentPlace;
}
}
}
var cardRetrieval = {
//return card vals
getCard: function (curHand) {
var q = curHand.push(deck.shoe.shift());
this.checkValue(curHand);
showCards(curHand, q);
if (deck.shoe.length <= 40) {
deck.shuffleDeck();
}
}
Everything works fine until the if statement at the bottom that checks if there are 40+ cards in the shoe array. But when it attempts to shuffle the deck again, it breaks.
The trouble is with this:
this.shoe.length = 0;
this.shoe = this.baseDeck;
You're not making a copy of the baseDeck into the shoe. Instead you're overwriting the reference to the empty Array you created for shoe, and you're replacing it with a reference to the same Array that baseDeck references.
So it works the first time you shuffle, because this.shoe.length = 0 is not yet affecting the baseDeck. But when you shuffle the second time, you're destroying the baseDeck. (Basically, with that first shuffle, you were using the baseDeck instead of a copy of it.)
Change it to this:
this.shoe.length = 0;
this.shoe = this.baseDeck.slice(0);
This will make a clean copy of baseDeck that is referenced by shoe each time.
There are 2 problems with your random number, 1) it will never be 0 - the first card in the deck, and 2) it may exceed the array size.
Use this instead:
var randomPlace = Math.floor(Math.random() * this.shoe.length);

Categories