splice() not updating items order of array within knockout.js - javascript

Following a prior post on how to update the order of an array. I followed the suggestion of Michael Best and used splice() to modify the ordering of my array on button click
self.moveup = function (itemIndex) {
var i = self.itemList.indexOf(itemIndex);
if(i >= 1){
var array = self.itemList();
self.itemList.splice(i-1, 2, array[i], array[i-1]);
}
Where I am having trouble is in incrementing the items in the array. From reading the usage of Array Splice The first param indicates where the change should occur for moving up I would think that would be i+1 , the value 2 indicates how many items in the array would change so no change there and then the range I thought would be the selected item array[i] and the end would be [i+1] as I am increasing the position.
self.itemList.splice(i+1, 2, array[i], array[i+1]);
In the attached fiddler you can see the values increase but the items do not actually change order they are only replicating when you hit the down button. I expected the result to be the same as when calling moveUp.
I'd appreciate any pointers on what I am missing here. http://jsfiddle.net/rlcrews/SCWmk/5/
-cheers

Almost there. Here's how I did it.
When moving an item up, you need to swap it with the previous item. Thus, you need to replace the elements at indices i-1 and i with array[i] and array[i-1], respectively. Your moveup method does exactly that, so all is good.
Now, when moving an item down, you need to swap it with the next item. Thus, you replace the elements at indices i and i+1 with array[i+1] and array[i], respectively. Your code however changes the elements i+1 and i+2, which is no good. Instead, you should be doing:
self.itemList.splice(i, 2, array[i+1], array[i]);
You start splicing at i (as you're removing the elements at i and i+1) and you replace them (insert at that index) with array[i+1] and array[i].
On another note, your check for whether you can move the item down is incorrect. The only item you should not move down is the last item, i.e. the element at index self.itemList().length-1. Thus, the check should look like if (i < array.length - 1) { ... } (see the fiddle).

Related

How to output random array entry -- then remove that item from the array afterwards?

In my program, when the user clicks a button, an item (a string) from an array gets randomly selected, and is then outputted to the user.
My goal is to introduce some kind of "remove this item from the array after displaying to the user" functionality, to prevent repeat outputs. That way, each time they're viewing a fresh item, and not seeing the same ones over and over again.
Here is my v1 version of coding this:
Array1 = [] // the full array of all items is contained in here.
Array2 = [] // this is the post-display holding bay for items the user has seen already.
After outputting an item to the user from Array 1? That item will be added to Array 2. BEFORE displaying any array items to a user? It will cross-reference the randomly selected item against the full list of items in Array2, basically using IF/ELSE IF logic. Something like this:
for (let i = 0; i < NumberOfArray2Items; i++) {
if (Array1ItemToDisplay === Array2[i]) {
NumberOfMatches = j++ // basically, increment a numerical variable, so that any value
// greater than 0 indicates, yes, it's been outputted to the user before
}
}
if (NumberOfMatches === 0) {
DisplayCurrentArrayItem();
} else if (NumberOfMatches > 0) {
SelectAnotherArrayItemToDisplay();
}
That's a rough version of what I have in mind, and frankly it sounds like a terrible solution because it requires two very lengthy programmatic steps:
Looping over every single item in Array2 for cross-referencing
Potentially running that dozens, maybe hundreds of times, if it continues to find matches each time it runs that block of code.
Is there some simpler, faster method of cross-refencing an item against an entire array? Or perhaps cross-referencing both arrays against each other, to only leave the remaining items that don't match, and then select from that intermediate list of items that hasn't yet been displayed?
These arrays will contain tens of thousands of items, so my concern is, as presently written, this code will take forever to execute. Is there some simpler, faster, more efficient solution I'm not seeing?
Here you go, each time the button is clicked a random element from the array is shown. That element is then removed - so no duplicates are shown.
const data = ['foo', 'bar', 'bat', 'baz'];
document.getElementById('btn').addEventListener("click", e => {
if(!data.length) return;
const idx = Math.floor(Math.random() * data.length);
console.log(data[idx]);
data.splice(idx, 1);
});
<button id=btn>click</button>
I also added a check to make sure that when there are no unique items left nothing happens, not sure if this is what you wanted or not. If not - remove the line if(!data.length) return;

Confused on reversing an array

I want to reverse an array that I input into a function.
But for some reason the console returns the first value of the array instead of taking the full array within the while loop so it can unshift the value at the end to the front then delete that same value.
function littleWHEW(lemonade) {
let i = lemonade.length - 1;
while (i >= 0) {
lemonade.unshift(lemonade[i])
lemonade.pop(lemonade[i])
i = i - 1
}
return lemonade
}
console.info(littleWHEW([1,2,3,4,5]))
Just use the
reverse()
method:
function littleWHEW(lemonade) {
return lemonade.reverse();
}
You should not add a parameter to the pop() method, by the way.
Since you asked for explanation, let's take a deep investigation. Before we do, please take a look at
unshift and pop
Firstly i = 4. Here're what happens in one loop:
[1,2,3,4,5] is the original array. lemonade.unshift(lemonade[i]) adds one element to the first position of lemonade. At this point i = 4 so lemonade[4] = 5, we have [5,1,2,3,4,5] (notice the bold).
Now you pop the last one out. [5,1,2,3,4,5] becomes [5,1,2,3,4].
You decrease i.
Now i = 3, And here're what happens in second loop:
[5,1,2,3,4] is the original array. lemonade.unshift(lemonade[i]) adds one element to the first position of lemonade. At this point i = 3 so lemonade[3] = 3, we have [3,5,1,2,3,4] (notice the bold).
Now you pop the last one out. [3,5,1,2,3,4] becomes [3,5,1,2,3].
You decrease i.
After one loop, your i does not point to the last element as expected, and makes things wrong (as second loop does).

Why is JavaScript adding extra square brackets when I push a sub array into another array?

I am working on a CodeWars kata that involves multidimensional arrays.
I have an array with three elements. Each element is an array with a name (string) and a sum (number).
I am checking the numbers. If they exceed a certain amount, I want to remove the sub array with that number and put it at the end of the array. I used splice() and push().
In a test case that had a sub array that had to be moved, the sub array was pushed to the end of the parent array. But, it had an extra set of brackets. I was wondering why this happened. Is JavaScript automatically adding the brackets when the push takes place because the parent array has only sub arrays as elements?
Here is a link to some screenshots of the Chrome Dev Tools and one from CodeWars. I combined them into one image.
The sub array at index 2 in the pop out window shows the sub array at the end that was moved/pushed in the first screenshot.
The second screenshot shows the expanded view.
The final screenshot I am attaching is the result shown in CodeWars where you can see the double brackets on the last sub array.
I cannot get the image to upload. So, here is a link to it online.
https://sta.sh/01tp7y7zaayi
Here is the section of code where this is happening.
I included the sort. But, I don't think it is affecting anything.
Note: I had a loop to go through the three elements to check them where the comment is located. But, I removed it because one shouldn't loop through an array and make changes to that array. I am coding a map() method for this to return a new array. But, I noticed that the double brackets were appearing. So, I didn't finish the map() part. I am trying to figure out what is happening in that splice() / push() section first.
var arrNew = [["Ben", sumBen], ["Amy", sumAmy], ["Sam", sumSam]];
arrNew.sort(function (a,b) {
if (a[1] < b[1]) return 1;
if (a[1] > b[1]) return -1;
if (a[0] > b[0]) return 1;
if (a[0] < b[0]) return -1;
return 0;
});
// If someone's score is over 21, move them to the back.
var forMoving = arrNew.splice(0, 1);
arrNew.push(forMoving);
Use Array.concat instead of push to concat arrays.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

JavaScript - Arrays - Deleting elements from an array

I've looked up arrays and how they work, looked at a lot of other stackoverflow questions on this same topic but the answer still doesn't remain clear. How can I remove a specified element from an array?
I've tried:
array.splice(5);
array.splice(i, 5);
delete array[5]; //doesn't actually delete - I know
1 of 2 things happen every time. 1. The whole array is deleted with either of the first 2 methods mentioned above. or 2. Everything before/after the element specified is removed.
For example, I had an array that contained a Clash Royale deck:
var deck = ["Barbarians", "Goblin_Barrel", "Inferno_Tower", "Fireball", "Zap", "Hog_Rider", "Spear_Goblins", "Minion_Horde"];
Then if I wanted to remove, lets say, Fireball, then I did:
deck.splice("Fireball");
And the array now looked like this:
deck = [];
So, to restate my question. How do I remove a specified, and only the specified, element from an array?
Check the usage for splice in a JavaScript reference. You need to pass in the index of the thing to delete, then how many things to delete.
First find the index of element then remove it using splice.
Find Index of element
var index = deck.indexOf("Fireball");
Now remove element using splice.
if (index > -1) {
deck.splice(index,1);
}
if duplicate values exists then
for(ind = 0 ; ind <deck.length; ind++){
if(deck[ind]=="Fireball"){
deck.splice(ind--,1);
}
}

JS / Jquery - Remove multiple elements from an array by keys

I have a set of keys (for example 2,3,4,101,102,454).
I'd like to remove elements with these keys from an array.
Is there a way to remove them all at once?
I tried iterating through for loop, and using splice
to remove elements one by one, but that never removed
all elements - my guess is because it modifies the
array I'm looping through.
go backwards.
If you loop thru from 0 -> n, you modify the indexes of the elements coming after an item you just removed.
If you go backwards, from n -> 0, you don't have that problem.
You can sort your indexes to remove largest first-
//array=array, removal=[2,3,4,101,102,454]
var i=0, L=removal.length;
removal.sort(function(a,b){return b-a});
while(i< L){
array.splice(removal[i],1);
}

Categories

Resources