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.
Related
Suppose I have an Javascript array,
var example = [and, there,sharma<br, />, ok, grt]
Now I want to randomly delete some array values - but not those values which have
<br
in them, in the above example, I want to make sure
"sharma<br" is not deleted.
I also do not want to delete "/>".
Can anyone help me. I would really appreciate the answer.
First of all, that is not a valid array, unless you are missing the string quotes. Anyway, what you are searching for is Array.Filter. In your case :
var filtered = example.filter(v => v.indexOf("<br") != -1 || v.indexOf("/>") != -1)
If I have understood the problem correctly, then you want to keep those entries in the array which have substrings "<br" and "/>"
If thats the case, you can try using javascript string method includes() to see if a string contains a particular substring.
JavaScript array must be created as below
var example = ["and"," there"",sharma<br","/>","ok"," grt"];
Using splice method , to delete the array values specifying the index positions.
array splice() method changes the content of an array, adding new elements while removing old elements.
Syntax
Its syntax is as follows −
array.splice(index, howMany, [element1][, ..., elementN]);
Parameter Details
index −
Index at which to start changing the array.
howMany −
An integer indicating the number of old array elements to remove. If howMany is 0, no elements are removed.
element1, ..., elementN −
The elements to add to the array. If you don't specify any elements, splice simply removes the elements from the array.
Return Value
Returns the extracted array based on the passed parameters.
var removed = arr.splice(2, 2);
This would remove your suggested output to be my assumption .
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
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'm trying to list out the elements from a json array using a for loop. There are 3 elements that I need to list but the elements in the array repeat several times and I only want each element to be listed once so I have an if statement that will remove the last element appended if the last element appended already exists.
for (var i=0, len=data.OCC_FiltersObj_Cust.length; i < len; i++) {
$("#filters").append("<optgroup id="+data.OCC_FiltersObj_Cust[i].CustomerType+" label="+data.OCC_FiltersObj_Cust[i].CustomerType+">");
if (data.OCC_FiltersObj_Cust[i].CustomerType===data.OCC_FiltersObj_Cust[i-1].CustomerType) {
$("#filters:last").remove();
}
}
My problem is that when this executes the loop stops entirely when it hits the if statement and only appends the first element. any help with fixing this or if you have a better way to do this I would be glad to hear it.
It stops because you're at index i=0 and you're referencing i-1 (which would be -1). Use the following if:
if (i > 0 && data.OCC_FiltersObj_Cust[i].CustomerType===data.OCC_FiltersObj_Cust[i-1].CustomerType) {
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.