Last question did not get well received as was a possible duplicate. Writing again to explain how this is slightly different as can't get the solution I want.
I have an array called _USERS and another one called newArray.
newArray looks like this:
newArray = ["BLRlXKIeWkanHiSCXbBCFRTIaqk1", "sF4gWbZvAMPmrbeHsKzln7LowOx2"]
_USERS is an array of objects and the objects have a property/attribute called useruid which equals a string. How can I remove an object from _USERS if the useruid string matches ANY string found in the newArray.
Solutions I have tried include:
for (var k = 0; k < newArray.length; k++){
if (_USERS[j].useruid == newArray[k]){
_USERS.splice(newArray[k])
}
var result = _.differenceWith(_USERS, newArray, _.isEqual);
neither of these have worked and I just cant quite put my finger on the missing piece
INITIAL _USERS CODE:
console.log(_USERS) => [Object, Object, Object, Object]
Each object has
gender: "male", name: "Rich", username: "[email protected]", useruid: "BLRlXKIeWkanHiSCXbBCFRTIaqk1"
newArray = ["BLRlXKIeWkanHiSCXbBCFRTIaqk1", "sF4gWbZvAMPmrbeHsKzln7LowOx2"]
newArray[0] = a string. This string matches the useruid in the Rich object. therefore I would like that to be deleted and then the below to happen
console.log(_USERS) => [Object, Object, Object]
5 Answers 5
It looks like a simple filter to me:
let filteredUsers = _USERS.filter(u => !newArray.includes(u.useruid))
Here it is in action:
var newArray = ["BLRlXKIeWkanHiSCXbBCFRTIaqk1", "sF4gWbZvAMPmrbeHsKzln7LowOx2"]
var _USERS = [{ gender: "male", name: "Rich", username: "[email protected]", useruid: "BLRlXKIeWkanHiSCXbBCFRTIaqk1" }]
let filteredUsers = _USERS.filter(u => !newArray.includes(u.useruid));
/*Printing*/
/*Before*/
document.write("Before: <br>" + JSON.stringify(_USERS) + "<br><br>");
/*After*/
document.write("After <br>" + JSON.stringify(filteredUsers));
1 Comment
Here's a simple solution if I understand your question:
_USERS = _USERS.filter(u => newArray.indexOf(u.useruid)===-1);
3 Comments
There are several clean ways to do this, but just to comment on your splice implementation. Splice expects the first parameter to be an index of an element not an object, so if you call splice(1) then it will delete from the object at index 1 to the end of the array. The second parameter is the number of elements that should be deleted, so splice(1, 1) will delete only the element at index 1. Here is some sample code that may help:
var newArray = ["xyz", "def"];
var _USERS = [
{useruid: "abc"},
{useruid: "def"},
{useruid: "ghi"}
];
for(var i = 0; i < _USERS.length; i++)
{
for(var j = 0; j < newArray.length; j++)
{
if(_USERS[i].useruid == newArray[j])
{
_USERS.splice(i, 1); //remove element at index i
i--; //decrement i because we now removed an element
break; //move to next element
}
}
}
2 Comments
To mutate your original array with a loop and Array#splice you need to run your loop in reverse as the length of the array and indexes of items in your array will change when you remove an item, and hence you will miss some of the items. Examples in ES6.
With a forward running loop, incorrect result.
function customRemove(users, unwanted) {
for (let user of users.entries()) {
if (unwanted.includes(user[1].useruid)) {
users.splice(user[0], 1);
}
}
}
const newArray = ['BLRlXKIeWkanHiSCXbBCFRTIaqk1', 'sF4gWbZvAMPmrbeHsKzln7LowOx2'];
const _USERS = [{
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk1'
}, {
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk1'
}, {
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk2'
}, {
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk1'
}];
console.log(JSON.stringify(_USERS));
customRemove(_USERS, newArray);
console.log(JSON.stringify(_USERS));
With a reverse running loop, correct result.
// Generator creates index number in reverse
function* reverseIndexes(arr) {
let key = arr.length - 1;
while (key >= 0) {
yield key;
key -= 1;
}
}
// Generator like Array#entries but in reverse
function* reverseEntries(arr) {
for (let key of reverseIndexes(arr)) {
yield [key, arr[key]];
}
}
function customRemove(users, unwanted) {
// Reversed loop removing unwanted matches with Array#splice
for (let user of reverseEntries(users)) {
if (unwanted.includes(user[1].useruid)) {
users.splice(user[0], 1);
}
}
}
const newArray = ['BLRlXKIeWkanHiSCXbBCFRTIaqk1', 'sF4gWbZvAMPmrbeHsKzln7LowOx2'];
const _USERS = [{
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk1'
}, {
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk1'
}, {
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk2'
}, {
useruid: 'BLRlXKIeWkanHiSCXbBCFRTIaqk1'
}];
console.log(JSON.stringify(_USERS));
customRemove(_USERS, newArray);
console.log(JSON.stringify(_USERS));
Comments
Well just to expand on @Denys answer. I have taken the .filter approach and added it to a jsfiddle. I've only included useruid for a user but that should be enough to filter as required.
_USERSdata? What was wrong with the result from the code that you have posted?_USERSarray