Prevent element from being added based on boolean - javascript

I have an array of ID's ("world") to iterate. If the world element value exists as myArray[n].id then I want to delete the entire element in myArray. If not, then I want to add it to myArray.
world = ["12424126","12461667","12492468","12761163"]
myArray = [
{"id": "12424126"},
{"id": "12761163"},
{"id": "12492468"}
]
Example: if the first element in world[n] ("12424126") exists in myArray as {"id": "12424126"} then delete the element {"id": "12424126"}
if the first element in world[n] ("12424126") does not exists in myArray, then
myArray.push ({"id":world[n]});
}
for (n = 0; n <= world.length; n++) {
ID = world[n];
finished = false;
if (myArray.find(x => x.id === ID)) {
var index = _.findIndex(myArray, { "id": ID });
if (index > -1) { myArray.splice(index, 1);
finished = true;}
}
if (!finished) // PROBLEM: THE RECORD IS ADDED REGARDLESS OF FINISHED T/F
{myArray.push ({id:ID }); // HOW CAN I FIX THIS ?
}
}

The following code works as you want
world = ["12424126", "12461667", "12492468", "12761163"];
myArray = [{ id: "12424126" }, { id: "12761163" }, { id: "12492468" }];
for (n = 0; n < world.length; n++) {
ID = world[n];
var index = myArray.findIndex((item) => item.id == ID);
if (index > -1) {
myArray.splice(index, 1);
} else {
myArray.push({ id: ID });
}
}

The problem is that your loop will make finished turn from true to false again in a next iteration of the loop. You would need to exit the loop immediately when finished is set to true.
However, this can be better solved with a Set:
const world = ["12424126","12461667","12492468","12761163"];
let myArray = [{"id": "12424126"},{"id": "12761163"},{"id": "12492468"}];
const set = new Set(myArray.map(({id}) => id).concat(world));
myArray = Array.from(set, id => ({id}));
console.log(myArray);
If you don't want to assign to myArray a new array, and not create new objects for those that already existed in the array, then:
const world = ["12424126","12461667","12492468","12761163"];
let myArray = [{"id": "12424126"},{"id": "12761163"},{"id": "12492468"}];
const set = new Set(myArray.map(({id}) => id).concat(world));
myArray.push(...Array.from(set).slice(myArray.length).map(id => ({id})));
console.log(myArray);
This second solution assumes however that myArray did not already have duplicate id values.

Related

How to Delete an item from an array with specific string matching

I want to be able to match a specific string (full match not partial match) and then delete that specific item from the array if it matches.
I have some code but it doesn't seem to be deleting the item from the array. I do wish for it to change the original array and not create a new array so I am not using filter.
How can I go about accomplishing this?
Current Code:
let recentSearches = [
{ name: "Chicago, IL" },
{ name: "Orlando, FL" },
{ name: "Dallas, TX" }
];
let stringToRemove = "Dallas, TX";
recentSearches.some(recent => {
if (recent.name === stringToRemove) {
const index = recentSearches.indexOf(stringToRemove);
if (index !== -1) { //Never goes into this if
recentSearches.splice(index, 1);
console.log(recentSearches);
}
}
});
console.log(recentSearches);
JS Fiddle: enter link description here
If you don't mind the output being a different array, use filter:
const filteredSearches = recentSearches.filter((recent) => recent.name !== stringToRemove);
If you need to modify the array in-place, you should visit the elements in reverse order (in case of multiple matches, which causes indices to shift) like so:
for (let i = recentSearches.length-1; i >= 0; i--) {
if (recentSearches[i].name === stringToRemove) {
recentSearches.splice(i, 1);
}
}
The problem with your code is you use recentSearches.indexOf, but recentSearches isn't an array of strings, so nothing matches. You could modify your code as follows, but it won't work correctly in case of multiple mathces:
recentSearches.forEach((recent, index) => {
if (recent.name === stringToRemove) {
recentSearches.splice(index, 1);
}
});
Alternatively, you could use findIndex (as suggested in other comments and answers) as follows:
let index;
while (0 <= (index = recentSearches.findIndex((recent) => recent.name === stringToRemove)) {
recentSearches.splice(index, 1);
}
indexOf() is for finding exact matches. Since your array contains objects, they'll never be equal to stringToRemove.
Use findIndex() to get the index of an array element using a function that an compare the name property.
There's also no need for using some().
let recentSearches = [{
name: "Chicago, IL"
},
{
name: "Orlando, FL"
},
{
name: "Dallas, TX"
}
];
let stringToRemove = "Dallas, TX";
const index = recentSearches.findIndex(({
name
}) => name == stringToRemove);
if (index !== -1) { //Never goes into this if
recentSearches.splice(index, 1);
}
console.log(recentSearches);
Another version of the findIndex, instead of using while, you could use for, a slight advantage here is that the index is then locally scoped inside the the for, were with a while loop you have the extra scope of the index, you could close the the scope of a let by doing { let index; while() {..}} but the for loop avoids that without using {}.
let recentSearches = [
{name: "Chicago, IL"},
{name: "Orlando, FL"},
{name: "Dallas, TX"}
];
let stringToRemove = "Dallas, TX";
for (let index; index = recentSearches.findIndex(
search => search.name === stringToRemove), index > -1;)
recentSearches.splice(index, 1);
console.log(recentSearches);
The JSON search is done wrongly.
I have added the perfect code to complete your requirement. Find all instances and delete them with a while loop. This will ensure duplicate search terms are also removed if any.
let recentSearches = [
{name: "Chicago, IL"},
{name: "Orlando, FL"},
{name: "Dallas, TX"}
];
let stringToRemove = "Dallas, TX";
while (recentSearches.findIndex(search => search.name === stringToRemove) > -1) {
const index = recentSearches.findIndex(search => search.name === stringToRemove);
recentSearches.splice(index, 1);
}
console.log(recentSearches);
You can use findindex.
Store it in a variable.
And use splice
You can use this code:
Array.prototype._arraycopy = function(src, srcPos, dest, destPos, length) {
while ((--length) >= 0) {
dest[destPos++] = src[srcPos++];
}
};
Array.prototype._fastRemove = function(es, i) {
let newSize;
if ((newSize = this.length - 1) > i)
this._arraycopy(es, i + 1, es, i, newSize - i);
es[this.length = newSize] = null;
this.length = newSize;
}
Array.prototype.__removeAt = function(index) {
// Objects.checkIndex(index, size);
const es = this;
const oldValue =es[index];
this._fastRemove(es, index);
return oldValue;
}
Array.prototype.__removeAtValue = function(o) {
const es = this;
const size = this.size;
let i = 0;
(function() {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
return true;
} else {
for (; i < size; i++)
if (Object.is(o, es[i]))
return true;
}
return false;
})()
this._fastRemove(es, i);
return true;
}
Array.prototype.remove = function(index) {
return this.__removeAt(index)
}
Array.prototype.removeObj = function(obj) {
return this.__removeAtValue(obj);
}
const arr = [1, 3, 4, 5, 10];
console.log(arr);
const rem = arr.remove(1)
console.log({ arr, rem });
const objs = [{ id: 1, name: "Hello" }, { id: 2, name: "Arrow" }, { id: 3, name: "Star" }]
console.log(objs);
const deleted = objs.removeObj({ id: 2, name: "Arrow" });
console.log({ objs, deleted })

Retrieve a specific value related to a key from a JSON array

I have a JSON array as follows
[{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}]
And I want to get the name of the Id which equals to 2(Id=2) through angularJS. I am a newbie to angularjs.
Array.find might be what you need:
> arr.find(e => e.Id === 2)
{ Id: 2, name: 'Test2' }
Try the below code:
var jsonArray = [{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}];
var name = Object.keys(jsonArray).find(e => {
if(jsonArray[e].Id == 2)
{
console.log(jsonArray[e].name);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Not the prettiest but this works
function findObjectByKey(array, key, value) {
console.log(array);
for (let i = 0; i < array.length; i++) {
console.log("looking for:", i);
if (array[i] !== undefined && array[i][key] === value) {
console.log("found at:", i);
return i;
}
}
return null;
}
array is the array you want to search
key would be 'id' in your case and
value woulde be 2 or whatever you are looking for
it returns the index of the object in the array but can easily be modified to return the name like this:
if (array[i] !== undefined && array[i][key] === value) {
console.log("found at:", i);
return array[i]['name'];
}
I know there is a more efficient way probably but this is what i first thought of
Assuming that you have this array:
var arr = [{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}];
You can always use a forEach through your array:
arr.forEach((a) => {if(a.Id == 2) console.log(a.name)});
Try below code,
let userArr = [{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}];
let userId = 2;
let item = userArr.find(e => {
return e.Id === userId;
});
console.log(item);
You can use also Filter JS Filter.

Add only unique objects to array

I have object created by function:
$scope.checkPosRole = function(possition , posRole , posFunction) {
var rolePos = {pos: possition, posRole: posRole, posFunction: posFunction};
$scope.rolePossition.push(rolePos);
};
The problem is that I want to in the array was only 1 object with the specified value of pos. In the case when the object is added with value pos that exists already in the array I want to swap new object with object exist already in array.
I've tried every function call scan the tables with foreach, but did not bring me desirable effect. Please help.
try this
var rolePosition = [{ id: 1}, {id: 2}, {id: 3}];
function addRolePosition(data) {
var index = -1;
for(var i = 0, i < rolePosition.length; i++) {
if(rolePosition[i].id === data.id) {
index = i;
}
}
if(index > -1) {
rolePosition[index] = data;
} else {
rolePosition.push(data)
}
}

Delete an object within an array, within another array [duplicate]

var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
How do I remove an object from the array by matching object property?
Only native JavaScript please.
I am having trouble using splice because length diminishes with each deletion.
Using clone and splicing on orignal index still leaves you with the problem of diminishing length.
I assume you used splice something like this?
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
All you need to do to fix the bug is decrement i for the next time around, then (and looping backwards is also an option):
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
To avoid linear-time deletions, you can write array elements you want to keep over the array:
var end = 0;
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) === -1) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
and to avoid linear-time lookups in a modern runtime, you can use a hash set:
const setToDelete = new Set(listToDelete);
let end = 0;
for (let i = 0; i < arrayOfObjects.length; i++) {
const obj = arrayOfObjects[i];
if (setToDelete.has(obj.id)) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
which can be wrapped up in a nice function:
const filterInPlace = (array, predicate) => {
let end = 0;
for (let i = 0; i < array.length; i++) {
const obj = array[i];
if (predicate(obj)) {
array[end++] = obj;
}
}
array.length = end;
};
const toDelete = new Set(['abc', 'efg']);
const arrayOfObjects = [{id: 'abc', name: 'oh'},
{id: 'efg', name: 'em'},
{id: 'hij', name: 'ge'}];
filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);
If you don’t need to do it in place, that’s Array#filter:
const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
You can remove an item by one of its properties without using any 3rd party libs like this:
var removeIndex = array.map(item => item.id).indexOf("abc");
~removeIndex && array.splice(removeIndex, 1);
With lodash/underscore:
If you want to modify the existing array itself, then we have to use splice. Here is the little better/readable way using findWhere of underscore/lodash:
var items= [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'},
{id:'hij',name:'ge'}];
items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);
With ES5 or higher
(without lodash/underscore)
With ES5 onwards we have findIndex method on array, so its easier without lodash/underscore
items.splice(items.findIndex(function(i){
return i.id === "abc";
}), 1);
(ES5 is supported in almost all morden browsers)
About findIndex, and its Browser compatibility
To delete an object by it's id in given array;
const hero = [{'id' : 1, 'name' : 'hero1'}, {'id': 2, 'name' : 'hero2'}];
//remove hero1
const updatedHero = hero.filter(item => item.id !== 1);
findIndex works for modern browsers:
var myArr = [{id:'a'},{id:'myid'},{id:'c'}];
var index = myArr.findIndex(function(o){
return o.id === 'myid';
})
if (index !== -1) myArr.splice(index, 1);
Check this out using Set and ES5 filter.
let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) );
console.log(result);
Here is JsFiddle:
https://jsfiddle.net/jsq0a0p1/1/
If you just want to remove it from the existing array and not create a new one, try:
var items = [{Id: 1},{Id: 2},{Id: 3}];
items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
Loop in reverse by decrementing i to avoid the problem:
for (var i = arrayOfObjects.length - 1; i >= 0; i--) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
Or use filter:
var newArray = arrayOfObjects.filter(function(obj) {
return listToDelete.indexOf(obj.id) === -1;
});
Only native JavaScript please.
As an alternative, more "functional" solution, working on ECMAScript 5, you could use:
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}]; // all that should remain
arrayOfObjects.reduceRight(function(acc, obj, idx) {
if (listToDelete.indexOf(obj.id) > -1)
arrayOfObjects.splice(idx,1);
}, 0); // initial value set to avoid issues with the first item and
// when the array is empty.
console.log(arrayOfObjects);
[ { id: 'hij', name: 'ge' } ]
According to the definition of 'Array.prototype.reduceRight' in ECMA-262:
reduceRight does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.
So this is a valid usage of reduceRight.
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
as per your answer will be like this. when you click some particular object send the index in the param for the delete me function. This simple code will work like charm.
function deleteme(i){
if (i > -1) {
arrayOfObjects.splice(i, 1);
}
}
If you like short and self descriptive parameters or if you don't want to use splice and go with a straight forward filter or if you are simply a SQL person like me:
function removeFromArrayOfHash(p_array_of_hash, p_key, p_value_to_remove){
return p_array_of_hash.filter((l_cur_row) => {return l_cur_row[p_key] != p_value_to_remove});
}
And a sample usage:
l_test_arr =
[
{
post_id: 1,
post_content: "Hey I am the first hash with id 1"
},
{
post_id: 2,
post_content: "This is item 2"
},
{
post_id: 1,
post_content: "And I am the second hash with id 1"
},
{
post_id: 3,
post_content: "This is item 3"
},
];
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 2); // gives both of the post_id 1 hashes and the post_id 3
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 1); // gives only post_id 3 (since 1 was removed in previous line)
with filter & indexOf
withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1));
withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);
with filter & includes
withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id)))
withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));
You can use filter. This method always returns the element if the condition is true. So if you want to remove by id you must keep all the element that doesn't match with the given id. Here is an example:
arrayOfObjects = arrayOfObjects.filter(obj => obj.id != idToRemove)
Incorrect way
First of all, any answer that suggests to use filter does not actually remove the item. Here is a quick test:
var numbers = [1, 2, 2, 3];
numbers.filter(x => x === 2);
console.log(numbers.length);
In the above, the numbers array will stay intact (nothing will be removed). The filter method returns a new array with all the elements that satisfy the condition x === 2 but the original array is left intact.
Sure you can do this:
var numbers = [1, 2, 2, 3];
numbers = numbers.filter(x => x === 2);
console.log(numbers.length);
But that is simply assigning a new array to numbers.
Correct way to remove items from array
One of the correct ways, there are more than 1, is to do it as following. Please keep in mind, the example here intentionally has duplicated items so the removal of duplicates can be taken into consideration.
var numbers = [1, 2, 2, 3];
// Find all items you wish to remove
// If array has objects, then change condition to x.someProperty === someValue
var numbersToRemove = numbers.filter(x => x === 2);
// Now remove them
numbersToRemove.forEach(x => numbers.splice(numbers.findIndex(n => n === x), 1));
// Now check (this is obviously just to test)
console.log(numbers.length);
console.log(numbers);
Now you will notice length returns 2 indicating only numbers 1 and 3 are remaining in the array.
In your case
To specifically answer your question which is this:
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
Here is the answer:
listToDelete.forEach(x => arrayOfObjects.splice(arrayOfObjects.findIndex(n => n.id === x), 1));
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
var result = arrayOfObjects.filter(object => !listToDelete.some(toDelete => toDelete === object.id));
console.log(result);

remove objects from array by object property

var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
How do I remove an object from the array by matching object property?
Only native JavaScript please.
I am having trouble using splice because length diminishes with each deletion.
Using clone and splicing on orignal index still leaves you with the problem of diminishing length.
I assume you used splice something like this?
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
All you need to do to fix the bug is decrement i for the next time around, then (and looping backwards is also an option):
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
To avoid linear-time deletions, you can write array elements you want to keep over the array:
var end = 0;
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) === -1) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
and to avoid linear-time lookups in a modern runtime, you can use a hash set:
const setToDelete = new Set(listToDelete);
let end = 0;
for (let i = 0; i < arrayOfObjects.length; i++) {
const obj = arrayOfObjects[i];
if (setToDelete.has(obj.id)) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
which can be wrapped up in a nice function:
const filterInPlace = (array, predicate) => {
let end = 0;
for (let i = 0; i < array.length; i++) {
const obj = array[i];
if (predicate(obj)) {
array[end++] = obj;
}
}
array.length = end;
};
const toDelete = new Set(['abc', 'efg']);
const arrayOfObjects = [{id: 'abc', name: 'oh'},
{id: 'efg', name: 'em'},
{id: 'hij', name: 'ge'}];
filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);
If you don’t need to do it in place, that’s Array#filter:
const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
You can remove an item by one of its properties without using any 3rd party libs like this:
var removeIndex = array.map(item => item.id).indexOf("abc");
~removeIndex && array.splice(removeIndex, 1);
With lodash/underscore:
If you want to modify the existing array itself, then we have to use splice. Here is the little better/readable way using findWhere of underscore/lodash:
var items= [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'},
{id:'hij',name:'ge'}];
items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);
With ES5 or higher
(without lodash/underscore)
With ES5 onwards we have findIndex method on array, so its easier without lodash/underscore
items.splice(items.findIndex(function(i){
return i.id === "abc";
}), 1);
(ES5 is supported in almost all morden browsers)
About findIndex, and its Browser compatibility
To delete an object by it's id in given array;
const hero = [{'id' : 1, 'name' : 'hero1'}, {'id': 2, 'name' : 'hero2'}];
//remove hero1
const updatedHero = hero.filter(item => item.id !== 1);
findIndex works for modern browsers:
var myArr = [{id:'a'},{id:'myid'},{id:'c'}];
var index = myArr.findIndex(function(o){
return o.id === 'myid';
})
if (index !== -1) myArr.splice(index, 1);
Check this out using Set and ES5 filter.
let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) );
console.log(result);
Here is JsFiddle:
https://jsfiddle.net/jsq0a0p1/1/
If you just want to remove it from the existing array and not create a new one, try:
var items = [{Id: 1},{Id: 2},{Id: 3}];
items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
Loop in reverse by decrementing i to avoid the problem:
for (var i = arrayOfObjects.length - 1; i >= 0; i--) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
Or use filter:
var newArray = arrayOfObjects.filter(function(obj) {
return listToDelete.indexOf(obj.id) === -1;
});
Only native JavaScript please.
As an alternative, more "functional" solution, working on ECMAScript 5, you could use:
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}]; // all that should remain
arrayOfObjects.reduceRight(function(acc, obj, idx) {
if (listToDelete.indexOf(obj.id) > -1)
arrayOfObjects.splice(idx,1);
}, 0); // initial value set to avoid issues with the first item and
// when the array is empty.
console.log(arrayOfObjects);
[ { id: 'hij', name: 'ge' } ]
According to the definition of 'Array.prototype.reduceRight' in ECMA-262:
reduceRight does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.
So this is a valid usage of reduceRight.
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
as per your answer will be like this. when you click some particular object send the index in the param for the delete me function. This simple code will work like charm.
function deleteme(i){
if (i > -1) {
arrayOfObjects.splice(i, 1);
}
}
If you like short and self descriptive parameters or if you don't want to use splice and go with a straight forward filter or if you are simply a SQL person like me:
function removeFromArrayOfHash(p_array_of_hash, p_key, p_value_to_remove){
return p_array_of_hash.filter((l_cur_row) => {return l_cur_row[p_key] != p_value_to_remove});
}
And a sample usage:
l_test_arr =
[
{
post_id: 1,
post_content: "Hey I am the first hash with id 1"
},
{
post_id: 2,
post_content: "This is item 2"
},
{
post_id: 1,
post_content: "And I am the second hash with id 1"
},
{
post_id: 3,
post_content: "This is item 3"
},
];
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 2); // gives both of the post_id 1 hashes and the post_id 3
l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 1); // gives only post_id 3 (since 1 was removed in previous line)
with filter & indexOf
withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1));
withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);
with filter & includes
withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id)))
withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));
You can use filter. This method always returns the element if the condition is true. So if you want to remove by id you must keep all the element that doesn't match with the given id. Here is an example:
arrayOfObjects = arrayOfObjects.filter(obj => obj.id != idToRemove)
Incorrect way
First of all, any answer that suggests to use filter does not actually remove the item. Here is a quick test:
var numbers = [1, 2, 2, 3];
numbers.filter(x => x === 2);
console.log(numbers.length);
In the above, the numbers array will stay intact (nothing will be removed). The filter method returns a new array with all the elements that satisfy the condition x === 2 but the original array is left intact.
Sure you can do this:
var numbers = [1, 2, 2, 3];
numbers = numbers.filter(x => x === 2);
console.log(numbers.length);
But that is simply assigning a new array to numbers.
Correct way to remove items from array
One of the correct ways, there are more than 1, is to do it as following. Please keep in mind, the example here intentionally has duplicated items so the removal of duplicates can be taken into consideration.
var numbers = [1, 2, 2, 3];
// Find all items you wish to remove
// If array has objects, then change condition to x.someProperty === someValue
var numbersToRemove = numbers.filter(x => x === 2);
// Now remove them
numbersToRemove.forEach(x => numbers.splice(numbers.findIndex(n => n === x), 1));
// Now check (this is obviously just to test)
console.log(numbers.length);
console.log(numbers);
Now you will notice length returns 2 indicating only numbers 1 and 3 are remaining in the array.
In your case
To specifically answer your question which is this:
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
Here is the answer:
listToDelete.forEach(x => arrayOfObjects.splice(arrayOfObjects.findIndex(n => n.id === x), 1));
var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
var result = arrayOfObjects.filter(object => !listToDelete.some(toDelete => toDelete === object.id));
console.log(result);

Categories

Resources