angularjs remove array specific element dosen't work - javascript

if I push two elements into another array and then try to remove the first one ( click at the first button ) the second element is being removed. why ?!?
DEMO
$scope.removeFromList = function(p) {
$scope.found = $.grep($scope.data2, function(e) {
return e.ID == p.ID;
});
var index = $scope.data2.indexOf($scope.found);
$scope.data2.splice(index, 1);
}

indexOf works for array not for Object. It returns -1, and so always take the last element.
Try this:
$scope.removeFromList = function (p) {
var index = $scope.data2.map(function(e) { return e.ID;}).indexOf(p.ID);
if(index >= 0)
$scope.data2.splice(index, 1);
}

This is happend because indexof is not used to find the objects and return -1 index always which in turn remove the first element always you need to create your own indexof
var index = myIndexOf($scope.data2,$scope.found);
function myIndexOf(arr,o) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].x == o.x && arr[i].y == o.y) {
return i;
}
}
return -1;
}
Plunker

Related

angularjs: check for an id exists in an array r not

var vm = this;
vm.usableDeposits = [];
for (var i = 0; i < billableChargeCodes.length; i++) {
var deposits = usableDeposits.filter(function(ud) {
return ud.billinggroupuid == billableChargeCodes[i].billinggroupuid ||
ud.billinggroupuid == billableChargeCodes[i].billingsubgroupuid ||
ud.departmentuid == billableChargeCodes[i].departmentuid ||
!ud.entypeuid ||
ud.entypeuid == entypeuid
})
for (var i = 0; i < deposits.length; i++) {
var depositid = deposits[i]._id;
first time, vm.usableDeposits[] is empty. I have to check deposits[i]._id exists in vm.usableDeposits[] or not. How to check vm.usableDeposits[] empty array _id with deposits[i]._id? if id not exists in vm.usableDeposits[], then i want to push the element into vm.usableDeposits[]
You can simply use the indexOf operator in JavaScript to check if a value exists in the array or not. It returns -1 if the value is not in the array, else, it returns the index of the element in the array.
The syntax goes like this -
if(myArray.indexOf(value) !== -1) {
// do this
} else {
// do that
}
Hope this helps.
You can use .some
deposits.some(o=> vm.usableDeposits.indexOf(o.id))
to check if the ID in deposits array is in vm.usableDeposits. .some will return true if condition is true and false otherwise
$scope.findIndexInData = function(data, property, value) {
var result = -1;
if((!!data) && (!!property) && (!!value)){
data.some(function (item, i) {
if (item[property] === value) {
result = i;
return true;
}
});
}
return result;
}
Pass on the array as the First Element. Property as second element and value you are looking in that array.
Example:
array = [{id:"1234",name:"abc"}, {id:"4567",name"xyz"}]
So you need to call:
index = $scope.findIndexInData(array , 'id' , 4567)

Removing outer array object if an inner array meets a condition

I am dealing with a fairly complex object. It contains 2 arrays, which contain 3 arrays each of objects:
I'm trying to delete one of the history: Array[2] if one of the objects in it has username: null.
var resultsArray = result.history;
var arrayCounter = 0;
resultsArray.forEach(function(item) {
item.forEach(function(innerItem) {
if (innerItem.username == null) {
resultsArray.splice(arrayCounter,1);
};
});
arrayCounter++;
});
Looking through answers it's recommended to do something like:
resultsArray.splice(arrayCounter,1);
This isn't working in this situation because more than one of the objects could have username == null and in that case it will delete multiple history objects, not just the one that I want.
How do I remove only the one specific history array index if username == null?
splice is evil. I think using immutable array methods like filter might be easier to reason about:
x.history =
x.history.filter(function (h) {
return !h.some(function (item) {
return item.username === null
})
})
Go through all the histories, and do not include them in the filter if they have a username that is null.
My understanding was that you only want to delete the first outer array that has an inner array that has an object with a null username. Heres one solution closest to your current form:
var resultsArray = result.history;
var arrayCounter = 0;
var foundFirstMatch = false;
resultsArray.forEach(function(item) {
if (!foundFirstMatch) {
item.forEach(function(innerItem) {
if (innerItem.username == null && !foundFirstMatch) {
foundFirstMatch = true;
};
});
arrayCounter++;
}
});
if (foundFirstMatch > 0)
resultsArray.splice(arrayCounter, 1);
Other syntax:
var resultsArray = result.history;
var outerNdx;
var innerNdx;
var foundMatch = false;
for (outerNdx = 0; !foundMatch && outerNdx < resultsArray.length; outerNdx++) {
for (innerNdx = 0; !foundMatch && innerNdx < resultsArray[outerNdx].length; innerNdx++) {
if (resultsArray[outerNdx][innerNdx].username == null) {
foundMatch = true;
}
}
}
if (foundMatch)
resultsArray.splice(outerNdx, 1);
Update - here's how I'd do it now, without lodash:
thing.history.forEach((arr, i) => {
thing.history[i] = arr.filter( (x) => x.username !== null );
});
Previous answer:
I'd use lodash like this:
_.each(thing.history, function(array, k){
thing.history[k] = _.filter(array, function(v){
return v.username !== null;
})
});
Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/n4sjjkwn/2/
You should write something like this:
var resultsArray = result.history.filter(function(item){
return !item.some(function(inner){ return inner.username==null; });
});
The foreach loop cant break in this way but a regular for loop can. This is working:
result.history.forEach(function(item) {
loop2:
for (var i = 0; i < item.length; i++) {
var innerItem = item[i];
console.log(innerItem);
break loop2;
}
});

Deleting Element After Pushing

If I have an array where I am pushing certain elements to a second array- how can I delete those elements from the first array after pushing them to the second? Here is sample code:
for(var a = 0; a < arr.length; a+=1){
if(arr[a].length == 4){
other.push(arr[a]);
}
}
In other words, I know longer want elements arr[a] to be in arr if they have been pushed to other.
Just do a splice on that original array index to remove that element if you no longer require it.
for(var a = 0; a < arr.length;){
if(arr[a].length == 4){
other.push(arr[a]);
arr.splice(a, 1);
}
else {
a += 1;
}
}
This seems fine:
for(var a = 0, length=arr.length; a < length; a++){
if(arr[a].length == 4){
other.push(arr[a]);
arr.splice(a,1);
}
}
Write a function which takes an input array, and a function to determine if an element should be moved. It returns a two-element array, containing the modified input, and the new array into which elements have been extracted.
function extractIf(array, condition) {
return [
array.filter(not(condition)),
array.filter( condition)
];
}
// Specify which elements are to be extracted/moved.
function condition(elt) { return elt.length === 4; }
// Little helper function to invert a function.
function not(fn) { return function() { return !fn.apply(this, arguments); }; }
Invoke this as:
var results = extractIf(arr, condition);
arr = results[0];
other = results[1];
underscore solution
If you are willing to use underscore, you could group the input by the true/false value of the condition:
var groups = _.groupBy(arr, function(elt) { return elt.length === 4; })
Your original array with the elements removed will be in groups.false, and the other array in groups.true.

How to remove elements from array satisfying condition

I want to delete json elements which are satisfying the condition. For that I used the given code
var index = -1;
for (var i = 0; i < data.dashLayout.dashlets.length; i++) {
if (data.dashLayout.dashlets[i].rowNo == selectedrowno) {
if (index == -1 || data.dashLayout.dashlets[i].rowNo < data.dashLayout.dashlets[index].rowNo) {
index = i;
}
}
if (index != -1) {
data.dashLayout.dashlets.splice(index, 1);
}
}
But iteration is not completing because the data.dashLayout.dashlets.length is reducing with splice. How can I solve this issue? I want to delete all items that are satisfying the condition. Please help
Another two solutions
var a = [2,5,8,13,9,1,4,8,10], l = a.length, c = 5;
// using reverse loop
while(l--){
if(a[l] < c) a.splice(l, 1);
}
// using filter
var b = a.filter(function(e, c) {
return --e > c;
});
console.log(a); // [5, 8, 13, 9, 8, 10]
console.log(b); // [5, 8, 13, 9, 8, 10]
If you split the array in the loop .the array will be reducing you should not iterate fully , so you have to think different idea . so my solution is you have to store the index based on that you have to remove the array .In the mean time every time the index will be changed so you have to use -1
var index = -1;
var arr = [] // make array
for (var i = 0; i < data.dashLayout.dashlets.length; i++) {
if (data.dashLayout.dashlets[i].rowNo == selectedrowno) {
if (index == -1 || data.dashLayout.dashlets[i].rowNo < data.dashLayout.dashlets[index].rowNo) {
index = i;
}
}
if (index != -1) {
// data.dashLayout.dashlets.splice(index, 1);
arr.push(index); //stored it
}
}
// to remove
for(var i in arr){
if (i == 0) {
data.dashLayout.dashlets.splice(arr[i], 1); // to remove init
} else {
data.dashLayout.dashlets.splice(arr[i] - 1, 1); // now index is changed now use -1
}
}
I would recommend using the filter method of the Array object. Filter method will return a new array which only contains the elements you want. Please see the definition of the filter method here
The usage will be like the code below
var newDashlets = data.dashLayout.dashlets.filter(function(dashlet, i) {
// Here your code returns true if you want to keep dashlet.
// Return false if you don't want it.
});
in jquery
data.dashLayout.dashlets = $.grep(data.dashLayout.dashlets, function (dashList, indexpos) {
if (dashList.rowNo == selectedrowno) {
if (dashList.rowNo < data.dashLayout.dashlets[index].rowNo || index == -1) {
index = indexpos;
return false;
}
}
});
Using map in jquery
data.dashLayout.dashlets = $.map(data.dashLayout.dashlets, function (dashList, indexpos) {
if (dashList.rowNo == selectedrowno) {
if (dashList.rowNo < data.dashLayout.dashlets[index].rowNo || index == -1) {
index = indexpos;
} else {
return dashList;
}
}
});

Check if each item in an array is identical in JavaScript

I need to test whether each item in an array is identical to each other. For example:
var list = ["l","r","b"]
Should evaluate as false, because each item is not identical. On the other hand this:
var list = ["b", "b", "b"]
Should evaluate as true because they are all identical. What would be the most efficient (in speed/resources) way of achieving this?
In ES5, you could do:
arr.every(function(v, i, a) {
// first item: nothing to compare with (and, single element arrays should return true)
// otherwise: compare current value to previous value
return i === 0 || v === a[i - 1];
});
.every does short-circuit as well.
function identical(array) {
for(var i = 0; i < array.length - 1; i++) {
if(array[i] !== array[i+1]) {
return false;
}
}
return true;
}
You could always do a new Set, and check the length.
var set1 = [...new Set(list)].length === 1;
The one line answer is:
arr.every((val, ind, arr) => val === arr[0]);
You can look into Array.every for more details.
Note:
Array.every is available ES5 onwards.
This method returns true for any condition put on an empty array.
Syntax: arr.every(callback[, thisArg]) or array.every(function(currentValue, index, arr), thisValue)
It does not change the original array
The execution of every() is short-circuited. As soon as every() finds an array element that doesn't match the predicate, it immediately returns false and doesn't iterate over the remaining elements
arr.every(i=>i==arr[0]) //will return true if all items in arr are identical
function matchList(list) {
var listItem = list[0];
for (index in list) {
if(list[index] != listItem {
return false;
}
}
return true;
}
var list = ["b", "b", "b"];
var checkItem = list[0];
var isSame = true;
for (var i = 0; i < list.length; i++) {
if (list[i] != checkItem) {
isSame = false;
break;
}
}
return isSame;
function identical(array) {
// a variable holding standard value
//against this standard value we are examining the array
var standard = array[1];
for (var i = 0; i < array.length; i++) {
if (array[i] !== standard) {
return false;
}
}
return true;
}
identical([1, 1, 1, 1, 1]); //return true
identical(['a', 'a', 'a']); //return true
identical(['a', 'a', 'b'])
function identical(array) {
// a variable holding standard value
//against this standard value we are examining the array
var standard = array[1];
for (var i = 0; i < array.length; i++) {
if (array[i] !== standard) {
return false;
}
}
return true;
}
identical([1, 1, 1, 1, 1]); //return true
identical(['a', 'a', 'a']); //return true
identical(['a', 'a', 'b'])
My suggestion would be to remove duplicates (check out Easiest way to find duplicate values in a JavaScript array), and then check to see if the length == 1. That would mean that all items were the same.
function allEqual(list)
{
if(list.length == 0 || list.length == 1)
{
return true;
}
for (index in list) {
if(list[index] != list[index+1] {
return false;
}
}
return true;
}

Categories

Resources