I have an array of objects:-
$scope.obj=[{"id":1,"content_type_name":"collections"},{"id":2,"content_type_name":"collections"},{"id":3,"content_type_name":"random"}];
Now when i try running my loop of angularForEach only the first collection entry(i.e. one with id=1 is getting removed but the one with id=2 stays). Ideally expected output should only be an object with id=3. Following is the code:-
angular.forEach($scope.obj, function(content, index){
if(content.content_type_name == "collections"){
$scope.obj.splice(index,1);
}
});
However when I run this, it works perfectly fine:-
for(var i=$scope.obj.length-1;i>=0;--i){
if($scope.obj[i].content_type_name == "collections"){
$scope.obj.splice(i,1);
}
}
I am not getting a clear picture of why splice is not working.
Some help please?
So the angular forEach loop starts at the beginning of the array, while your second example with the for loop starts at the end and goes back through. Since you're removing an element when 'collections' is found as the content_type_name, that will shift the index of every other item in the array down 1.
In the Angular forEach loop, it starts on index 0, removes it, then moves on to index 1, which is now the final element in the array since one was just removed. Basically it's skipping over the second element.
Your second example, using the for loop, doesn't have this problem since it's moving backwards through the array. So it checks index 2, doesn't do anything, checks index 1, removes it, and moves on to index 0, which it also removes. Hope I worded this well enough...
Maybe you are looking for a filter
$scope.obj = $scope.obj.filter(function(e){
return e.content_type_name == "collections"
});
Then you don't have to remove every single element
Related
a = ['a','b','c','d','e'];
console.log(a.splice(1));
console.log(a);
In splice documentation, it says that skipping the delete parameter will delete all array items, yet here they're not; the first one is left out. Why is this?
Edit: My expectations was that haveing the omission of the delete parameter would cause to delete all the items of the array. But now after read Baconnier comment I understand that removes all after the index (first parameter).
then all the elements from start to the end of the array will be deleted. start being 1 in your case.
a = ['a','b','c','d','e'];
console.log(a.splice(0));
console.log(a);
Arrays start at 0, if you want to delete all elements including the first one you need to pass 0 as the first parameter.
I have color templates that users can choose between and also change the individual colors if they want. I have two arrays: one with all the templates, and each template containing a color palette of 8 total colors and a string of the template name. Most of my templates have white backgrounds, so I don't want the user to have to click 12 times or however many it takes to get to another index where the background color is different. My idea was to use a "for" statement to check the next element in my array, and compare it to the current element to see if they are identical. If the elements are identical, then I increment the array and the "for" statement checks again, effectively skipping any duplicate indices until a new value is found.
To do this, I use a "for" statement like this:
( ; array[index][colorSlot] == array[index+1][colorSlot]; index++)
This works perfectly until I get to the last array index and it looks for the next index which obviously doesn't exist, thus completely breaking my function. Is there a way to prevent it from looking into an array index that doesn't exist? Should I use something other than a "for" statement?
You'd prob want to go up to the second last array index and skip all repeats.
for(let index=0; index<array.length-2; index++)
{
if[index][colorSlot] != array[index+1][colorSlot]
{
}
}
You can try it with a while loop it's better choice than a for-loop in your case.
let index = 0;
while (index < array.length -2 && array[index][colorSlot] != array[index+1][colorSlot] ) {
...
index++;
}
Ok, I figured it out.
In my for loop, I check for two conditions: FIRST, I check to see if [index+1]!=array.length and THEN I check to see if the current array value is equal to the next (as written above). If checking the next value of the index would cause it to search an index that does not exist, it exits the for statement and resets my index.
I have a sparse Array.
I use delete array[id] and I also want to adjust the length of the array after deletions. This is a pseudocode.
....
deleted =0;
...
if (condition) { delete array[id]; deleted++;}
...
array.length-=deleted;
Ok. I dont know what happen, the array has the expected length but ... it is empty!
Any idea what is happen?
Right way to delete an element from sparse array is :
arr.forEach(elm,index){
//delete index element
delete arr[index]
}
This removes the element but leaves the array size same
If you really want to do it manually and don't care about the order of items, the following is much faster than splice, but this messes up your order:
array[id] = array[array.length-1]; // copy last item to the index you want gone
array.pop(); // rremove the last item
The length of the array is automatically correct.
If you want to keep your order do what zerkms said and use splice
array.splice(id, 1);
The first parameter is the index from where you start. The second parameter is how many items you delete.
The length of the array is also correct.
I try to remove the first Item so that all other move up in an Array I create with
..
Queue: [],
..
and dynamically push Items into.
I later use slice to remove them and have then next Item be the first one.
..
thread.Queue.slice(0, 1);
..
It should return the first Item of the Array, which it does, but it should also remove it from the array and move all other up.
Here is a example which shows, that is neither working in the Browser. (I found this 'behaviour' in Node.js)
http://jsfiddle.net/bTrsE/
or rather
http://gyazo.com/b3dcdbf4f74642c04fe1c1025f225a08.png
Array.Slice = Is an implementation of SubArray, From an array you want to extract certain elements from the index and return a new array.
Example:
var cars = ['Nissan','Honda','Toyota'];
var bestCars = cars.splice(0,1);
console.log(bestCars);
//This should output Nissan Because i like Nissan
For your problem you should be looking Array.Splice(), splice adds / removes an element from the index
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
The .slice() method does not alter the original array. It returns a shallow copy of the portion of the array you asked for.
I need help with a loop... it's probably simple but I'm having difficulty coding it up.
Basically, I need to check existing Ids for their number so I can create a unique id with a different number. They're named like this: id="poly'+i'" in sequence with my function where i is equal to the number of existing elements. Example: Array 1, Array 2, Array 3 corresponding with i=1 for the creation of Array 1, i=2 for Array 2, etc.
Right now i is based on the total number of existing elements, and my "CreateNew" function is driven off x=i+1 (so the example above, the new element will be named Array 4). The problem is that if you delete one of the middle numbers, the "Create" function will duplicate the high number. i.e. Array 1, 2, 3 delete 2, create new-> Array 1, 3, 3.
I need an if() statement to check if the array already exists then a for() loop to cycle through all i's until it validates. Not sure how to code this up.
The code I'm trying to correct is below (note I did not write this originally, I'm simply trying to correct it with my minimal JS skills):
function NewPanel() {
var i = numberOfPanels.toString();
var x = (parseInt(i)+1).toString();
$('#items').append('<div onclick="polygonNameSelected(event)" class="polygonName" id="poly'+i+'"> Array '+ x +' </div>');
$('div[id*=poly]').removeClass('selected');
$('#poly'+i).addClass('selected');
$('#poly'+i).click(function() {
selectedPolygon = i;
$('div[id*=poly]').removeClass('selected');
$(this).addClass('selected');
});
}
THANK YOU! :)
Please clarify "The problem is that if you delete one of the middle numbers, ". What do you mean by delete? Anyway, the simplest solution is to create two arrays. Both arrays will have the same created id's. Whenever an id is created in the first array, an id will be added to the second array. So when it is deleted from first array, check your second array's highest value and then create this id in first array. I hope this did not confuse you.
Well it is hard to tell why you cannot just splice the array down. It seems to me there is a lot of extra logic involved in the tracking of element numbers. In other words, aside from the index being the same, the ids become the same as well as other attributes due to the overlapping 1, 3, 3 (from the example). If this is not the case then my assumption is incorrect.
Based on that assumption, when I encounter a situation where I want to ensure that the index created will always be an appending one, I usually take the same approach as I would with a database primary key. I set up a field:
var primaryKeyAutoInc = 0;
And every time I "create" or add an element to the data store (in this case an array) I copy the current value of the key as it's index and then increment the primaryKeyAutoInc value. This allows for the guaranteed unique indexing which I am assuming you are going for. Moreover, not only will deletes not affect future data creation, the saved key index can be used as an accessor.