javascript array pop without another foreach loop - arrays

my test array has multiple objects in them that I want to iterate over and if a condition is not met I want to pop it from main array.
I am using foreach loop. so
so I am using a foreach loop and doing
$.foreach(test, function(idx, val){
if(true){
test.splice(idx, 1);
}
});
problem is that it doesn’t work as if there are two objects for example, as shown below, it will reindex the array after the first iteration and then the second iteration which will be idx 1, will not be able to do
test.spice(1,1) since index 1 does not exist in the array anymore.
Now I know that I can create a temporary place holder and the indexes there and then run another foreach but thats what I am trying to avoid. Any ideas will be appreciated
[
email: “testemail#emailcom”
firstName: “Test"
]
[
email: “testemail2#emailcom”
firstName: “Test"
]

If you want to remove elements from an array, I recommend you to use filter function
test = test.filter(function(val, idx) {
if(true) { // a condition about val
return false; // return false to EXCLUDE
} else {
return true; // return false to INCLUDE
}
});

Just iterate through the array backwards. Then, removing elements from the array only affects the indices of elements that the loop has already dealt with:
for (var idx = test.length-1; idx>=0; idx--){
if(true){
test.splice(idx, 1);
}
}

Related

Difference between these two functions that handle the state

I tried these two functions and I thought they do the same thing, but apparently no.
The first Function:
setEatenFoodList(prevList => {
const newList = [];
for (let i=0 ; i<prevList.length ; i++) {
if (i === index){
const editedFood = prevList[i];
editedFood.removingFade = true;
newList.push(editedFood)
} else {
newList.push(prevList[i])
}
}
return newList;
})
The second Function:
setEatenFoodList(prevList => {
prevList[index].removingFade = true;
return prevList;
})
I don't see the difference ?
The first code creates a new list called "newList" and iterates through the elements of the original list "prevList" and adds them to the new list. If the current index of the loop is equal to the variable "index", it creates a new variable called "editedFood" which is a copy of the element at that index, sets the "removingFade" property of "editedFood" to true and pushes it to the "newList". Finally, it returns the "newList" as the output.
The second code is simpler, it directly modifies the "prevList" by setting the "removingFade" property of the element at index "index" to true. And it returns the original list "prevList" as output.
The main difference between the two codes is that the first one creates a new list, whereas the second one modifies the original list.
More simply: the first function iterates through all the elements of newList and pushes everything inside the newList. The second function pushes everything into the original list (prevList)

how to add an object to array immediately after set to empty "[ ]" Vue

I need after call a function, set to empty an array and immediately add a new one to there.
This is becouse when an #click event is called i need to call a dialog and populate the content of this with a dynamic component (called them with a slug propertie), so the array should be change accordily to pass the slug propertie to the component.
My code is:
slugs: []
slugConversacion(slug) {
if (this.slugs > 0) {
this.slugs = []
// this.slugs.splice(this.slugs.indexOf(slug), 0);
// this.$delete(this.slugs, this.slugs.indexOf(slug))
}
else {
this.slugs.push(slug);
}
}
<Conversacion
v-for="slug in slugs"
:key="slug.id"
:slug="slug.slug"
></Conversacion>
This not work because when i click the event slugConversacion() set and empty array and only when clicked again, populate. I think that is for the if/else conditional.
What would be the right approach ? Thanks!
Just do this:
if (this.slugs.length > 0) {
this.slugs = [];
}
this.slugs.push(slug);
If you have trouble with setting array to empty with assigning [] to array and loosing reactivity, then you can try next thing.
This works for me as the last resort:
var i = slugs.length;
while(i --){
slugs.splice(i, 1);
}
You should do splice in revers mode because of index confusion: every time will be remained array element with index 1 if you will go throw the loop via
slugs.forEach((item, index) => {
slugs.splice(index, 1);
});
And after that you can do:
this.slugs.push(slug);

Remove tuple from array of tuples

Func to see if two arrays have some same values:
func hasAllSame(largeCombinedArry:[Int], wantToKeep: [Int])->Bool{
var howManySame = [Int]()
for intElement in largeCombinedArry{
if wantToKeep.contains(intElement){
howManySame.append(intElement)
}
}
howManySame.sort()
if wantToKeep == howManySame{
print("These are the same!")
return true
}
else{
print("These are NOT same!")
return false
}
}
Array of tuples declared like this:
var TuplesArry:[(score: Double, value: [Int])] = []
Array filled thusly:
for (arry1, score) in zip(arryOfArrays, AllScores) {
let calculatedDiff = otherValue - score
TuplesArry.append((score: calculatedDiff, value: arry1))
}
var arrayForComparison = [8,9,7,6]
arrayForComparison.sort()
Error occurs here after several iteration at function call hasAllSame()
for i in 0..<TuplesArry.count{
if hasAllSame(largeCombinedArry: TuplesArry[i].value, wantToKeep:
arrayForComparison){
//do nothing
}
else{
/*
want to remove tuple that does not have all elements that are
in arrayForComparison
*/
TuplesArry.remove(at: i)
}
}
This code seems to be working but it seems like tuplesArry.count continues to decrease and iterator i continues to increase until error occurs "fatal index out of range"
My goal is to remove a tuple from the array of tuples if it's value does not meet criteria.
I've also tried something like:
for tuple in TuplesArry{
if hasAllSame(largeCombinedArry: tuple.value, wantToKeep:
arrayForComparison){
//do nothing
}
else{
//this does NOT work
let index = TuplesArry.index(of:tuple)
TuplesArry.remove(at: index)
}
}
The immediate issue is that you need to iterate in reverse to avoid the "index out of range" issue.
The much simpler solution is to use filter on your array. Then you entire for loop can be replaced with:
TouplesArry = TouplesArry.filter { hasAllSame(largeCombinedArry: $0.value, wantToKeep: arrayForComparison) }

Removing records that exist in an array from ExtJS store

I have a store and an array. I want to remove records from the store if that record's value matches with values in the array. Following is is the code I am trying but it's not working. Can anyone suggest the correct way?
'store' is the actual store and 'filterItems' is the array of records I want to remove from 'store'.
store.each(function (record) {
for (var i = 0; i < filterItems.length; i++) {
if (record.get('ItemId') === _filterItems[i].get('ItemId')) {
itemIndex = store.data.indexOf(record);
store.removeAt(itemIndex );
}
}
});
Not sure about your code because i dont know all variables. Though its recommended to use the store.getRange() fn and iterate the array via for loop. Its better for performance.
var storeItems = store.getRange(),
i = 0;
for(; i<storeItems.length; i++){
if(Ext.Array.contains(filterItemIds, storeItems[i].get('id')))
store.remove(store.getById(storeItems[i].get('id')));
}
Here is an example which i tried right now and it works well.
https://fiddle.sencha.com/#fiddle/8r2
Try using the remove method of the store (docs)
store.remove(filterItems);
var indexes = [], i = 0;
dataviewStore.each(function(item, index){
if(item) {
if(item.data.columnId == columnId) {
indexes[i++] = index;
}
}
}, this);
dataviewStore.remove(indexes);
this is my example if your record is matches with the value then store the index of that item after storing indexes of all the items and remove them.
Otherwise you have to use for loop and remove them from end of the array.

How would I remove a "row" in an array depending on the value of an element?

Here's what I'm currently doing/trying to do to accomplish my goal. But it is not removing the "row" the way I would like it too.
So, I'm making an object, then pushing it into an array. And the adding to the array part works fine and just as I expect.
var nearProfileInfoObj:Object = new Object();
nearProfileInfoObj.type = "userInfo";
nearProfileInfoObj.dowhat = "add";
nearProfileInfoObj.userid = netConnection.nearID;
nearProfileInfoObj.username = username_input_txt.text;
nearProfileInfoObj.sex = sex_input_txt.selectedItem.toString();
nearProfileInfoObj.age = age_input_txt.selectedItem;
nearProfileInfoObj.location = location_input_txt.text;
nearProfileInfoObj.headline = headline_input_txt.text;
theArray.push(nearProfileInfoObj);
So after that later on I need to be able to remove that object from the array, and it's not working the way I'm expecting. I want to take a variable whoLeft and capture their ID and then look in the array for that particular ID in the userid part of the object and if its there DELETE that whole "row".
I know you can do a filter with an array collection but that doesnt actually delete it. I need to delete it because I may be adding the same value again later on.
whoLeft = theiruserIDVariable;
theArray.filter(userLeaving);
public function userLeaving(element:*, index:int, arr:Array):Boolean
{
if (element.userid == whoLeft)
{
return false;
}
else
{
return true;
}
}
But this doesnt seem to be deleting the whole row like it implies. Does anyone know what i'm doing wrong?
Instead of modifying the original array, the new filtered array is returned by the filter method. So you need to assign the returned array to theArray.
Try this
theArray = theArray.filter(userLeaving);
EDIT This turned out to be slower than for loop:
An alternative to the hand coded loop could be something like this:
theArray.every(searchAndDestroy);
public function searchAndDestroy(element:*, index:int, arr:Array):Boolean
{
if (element.userid == whoLeft)
{
arr.splice(index,1);
return false;
}
return true;
}
As far as I know, every() terminates the first time the test function returns false. So the question is: for a big list, which is faster, the for loop or the loop that every() does with the overhead of the test function call.
EDIT #2 But this was faster than a for loop for a test I ran on an array of a million Points:
for each(var element:Object in theArray)
{
if (element.userid==whoLeft)
{
theArray.splice(theArray.indexOf(element),1);
break;
}
}
I think this is what you're looking for:
for(var i:uint = 0, len:uint = theArray.length; i<len; i++)
{
if(thisArray[i].id == whoLeft.id)
{
thisArray.splice(i, 1);
break;
}
}
However, do you really need it in an Array because you could always use a Dictionary which would mean accessing it by id which would be a lot simpler to remove.

Resources