Remove an array element if one of the property contains certain values - javascript

I have following variable:
var data = [{id: '1', name: 'demo1'}, {id: '2', name: 'demo2'}, {id: '3', name: 'demo3'}]
Now I have another list of ids,
var lookFor = ["2", "3"];
Now, from data how will I remove the objects with id not available in the lookFor array of ids.
I tried with following
_.filter(data, function(item) {
return _.contains(lookFor, 'id');
});
Is there any other way?

Uhm consider the following?
var data = [{id: '1', name: 'demo1'}, {id: '2', name: 'demo2'}, {id: '3', name: 'demo3'}];
var keys = ["2", "3"];
let filteredArray = data.filter(element => keys.indexOf(element.id) != -1);
console.log(filteredArray);
// Output is now
// 0: {id: "2", name: "demo2"}
// 1: {id: "3", name: "demo3"}
Use this the get the opposite:
let filteredArray = data.filter(element => keys.indexOf(element.id) == -1);
console.log(filteredArray);
// Output is:
// 0: {id: "1", name: "demo1"}
Is that what you want?
Have a nice day, Elias

You can use functor filter for array and method includes to
determine whether an array includes a certain element
var res = data.filter(el=>!lookFor.includes(el.id));
result
[{id: "1", name: "demo1"}]
Opposite
var res = data.filter(el=>lookFor.includes(el.id));

You could use _.remove(array, [predicate=_.identity]) as following. Notice that this mutates the value of data.
var data = [{id: '1', name: 'demo1'}, {id: '2', name: 'demo2'}, {id: '3', name: 'demo3'}];
var lookFor = ["2", "3"];
_.remove(data, function(n) {
return _.indexOf(lookFor, n.id) === -1;
});
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

Here are just a few examples of how you can achieve this with ES6 only or with lodash. There are obviously more ways to do it but those should give you an idea. Also note that most of the examples do not mutate the arrays utilized:
var data = [{id: '1', name: 'demo1'}, {id: '2', name: 'demo2'}, {id: '3', name: 'demo3'}]
var lookFor = ["2", "3"];
// Does not mutate the array and uses ES6 Filter
var withFilter = data.filter(x => lookFor.indexOf(x.id) >= 0)
// Does not mutate the array and uses ES6 Reduce
var withReduce = lookFor.reduce((r,c) => r.push(data.find(x => x.id === c) || []) && r,[])
// Does not mutate the array with Lodah Filter
var withLodashFilter = _.filter(data, x => _.includes(lookFor, x.id))
// Mutates the array with Lodash Remove
var withLodashRemove = _.remove(data, x => _.includes(lookFor, x.id))
console.log('ES6 Filter', withReduce)
console.log('ES6 Reduce', withFilter)
console.log('Lodah Filter', withLodashFilter)
console.log('Lodash Remove', withLodashRemove)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Related

Compare one array with a nested array and push value into a new array with same index in Javascript

I have 2 arrays
const arrayOne = [
{id: '110'},
{id: '202'},
{id: '259'}
];
const arrayTwo = [
{data: [{value: 'Alpha', id: '001'}]},
{data: [{value: 'Bravo', id: '202'}]},
{data: [{value: 'Charlie', id: '110'}]},
{data: [{value: 'Delta', id: '202'}]}
];
I need to create a new array comparing arrayOne[idx].id with arrayTwo[idx].data[idx2].id
Upon match, I need to create an array pushing value (arrayTwo[idx].data[idx2].value) to the new array against each index in arrayOne.
In this example, I would get newArray = [null, 'Bravo', null, Delta]
What I have tried:
arrayOne.map(item => ({
...item,
result: arrayTwo.filter(itemTwo => item.data.map(x => x.id).includes(itemTwo.id))
}));
and also
const newArr = [];
arrayOne.map((item, idx) => {
if (arrayTwo.filter(itemTwo => itemTwo.data?.map(x => x.id) === item.id)) {
newArr.push(arrayTwo.data[idx].value);
} else newArr.push(null);
});
To do this you can map arrayTwo and use .find() to search for the ID in arrayOne. I also mapped arrayTwo to the inner object to make the second map more concise.
const arrayOne = [
{id: '110'},
{id: '202'},
{id: '259'}
];
const arrayTwo = [
{data: [{value: 'Alpha',id: '001'}]},
{data: [{value: 'Bravo',id: '202'}]},
{data: [{value: 'Charlie',id: '777'}]},
{data: [{value: 'Delta',id: '202'}]}
];
const result = arrayTwo
.map(obj => obj.data[0])
.map(obj => (arrayOne.find(v => v.id === obj.id) && obj.value) || null)
console.log(result)
Use map to iterate over each element of arr1 and return a new array.
Reassemble the data attribute array of each element in the arr2 array
using map and flat
When arr1 traverses, you can get the current element id, use filter
to filter the combined data array, and return an element array that matches
the current element id.
Based on the case where the id is not matched, use the optional chain operator to get the value.
When returning
if you want to get the element array of the id and
value attributes, use conditional (ternary) operator, when it doesn't match, return the original element,
when it matches, use spread syntax, copy the current element
attribute, and add the value attribute
if you only want to get an
array of matching results, just return the value,
remember to use the optional chain operator to convert the unmatched
value to null.
const arr1 = [
{ id: '110' },
{ id: '202' },
{ id: '259' }
];
const arr2 = [
{ data: [{ value: 'Alpha', id: '001' }] },
{ data: [{ value: 'Bravo', id: '202' }] }
];
const result1 = arr1.map(o1 => {
const data = arr2.map(o2 => o2.data).flat();
const value = data.filter(o2 => o2.id === o1.id)[0]?.value;
return value ? {...o1, value} : o1;
});
const result2 = arr1.map(o1 => {
const data = arr2.map(o2 => o2.data).flat();
const value = data.filter(o2 => o2.id === o1.id)[0]?.value;
return value ?? null;
});
[result1, result2].forEach(r => console.log(JSON.stringify(r)));
You can try this easy line of code :
const arrayOne = [{ id: '110' }, { id: '202' }, { id: '259' }];
const arrayTwo = [{ data: [{ value: 'Alpha', id: '001' }], }, { data: [{ value: 'Bravo', id: '202' }] }];
let result = arrayOne.map(el => {
let found = arrayTwo.find(f => f.data.at(0)?.id == el.id)?.data.at(0)?.value;
return { id: el.id, value: found ?? null};
});
console.log(result);

Delete multiple objects in an array by id

I have a main array of objects with each object having some key/values as well as a "id" key with 1,2,3,4,5, etc
Now I have another array representing just id's (like [2,3])
I want to use this array to delete objects from the main array...so in this case, objects from the main array having id's 2 & 3 should be deleted
While I am aware of findBy(id), I am not sure if that can be used to delete multiple objects at once.
You can use filter. In the filter callback function check if the id is also there in id array by using includes
let idArr = [1, 2]
let obj = [{
id: 1,
name: 'abc'
},
{
id: 2,
name: 'abc'
},
{
id: 3,
name: 'abc'
},
{
id: 4,
name: 'abc'
}
];
let data = obj.filter(item => !idArr.includes(item.id));
console.log(data);
console.log(obj)
using filter might work well here. you could write something like:
var newArray = oldArray.filter(object => !ids.includes(object.id))
You can do it, like this:
[2,3].forEach(key => {
delete object[key];
})
You can use filter method for this.
Ex:
let id = 2;
let list = [{
Id: 1,
Name: 'a'
}, {
Id: 2,
Name: 'b'
}, {
Id: 3,
Name: 'c'
}];
let lists = list.filter(x => {
return x.Id != id;
})
console.log(lists);
Assuming you want to delete items from the original array by entirely removing the element from the array (and you don't want to get a new array), you can take advantage of
Array.splice
let idArr = [1, 2];
let obj = [{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
}
];
for (let id of idArr) {
// look for the element by its id.
const objIdRef = obj.find(i => i.id === id);
// if it actually exists, splice it.
objIdRef && obj.splice(obj.indexOf(objIdRef), 1);
}
console.log(obj);
If the obj array is big, you might want to make a map from it before processing the id array, so that the complexing is reduced to O(1) when the delete process begins.
Perhaps This is what you want:
var arr= [{id:1, name: "foo"}, {id:2, name: "bar"}, {id:3, name:"not to be deleted"}];
var idsToDelete = [1, 2];
var res = arr.map((i, idx)=>{
return arr[idx] = idsToDelete.includes(i.id)? undefined : arr[idx]
}).filter(i=>i)
console.log(res)
You can try Lodash.js functions _.forEach() and _.remove()
let valuesArr = [
{id: 1, name: "dog"},
{id: 2, name: "cat"},
{id: 3, name: "rat"},
{id: 4, name: "bat"},
{id: 5, name: "pig"},
];
let removeValFromIndex = [
{id: 2, name: "cat"},
{id: 5, name: "pig"},
];
_.forEach(removeValFromIndex, (indi) => {
_.remove(valuesArr, (item) => {
return item.id === indi.id;
});
})
console.log(valuesArr)
/*[
{id: 1, name: "dog"},
{id: 3, name: "rat"},
{id: 4, name: "bat"},
]; */
Don't forget to clone (_.clone(valuesArr) or [...valuesArr]) before mutate your array

Check and get data from an array in JavaScript

I have an object:
var Obj1 = {id: 1, name: 'Apple'}
And an array object:
var ArrObj = [ {id: 1, name: 'Apple', 'eat': 'rice}, {'id: 2', 'name': 'Banana'}]
How do I check Obj1.id in ArrObj? And I want the result to be: { id:1, name: 'Apple', 'eat':'rice'}
You can use Array.find():
var Obj1 = {id: 2, name: 'Banana'}
var ArrObj = [ {id: 1, name: 'Apple', 'eat': 'rice'}, {'id': 2, 'name': 'Banana'}];
var res = ArrObj.find(({id}) => id === Obj1.id );
console.log(res);
You can also use array destructuring way like:
var Obj1 = {id: 2, name: 'Banana'}
var ArrObj = [ {id: 1, name: 'Apple', 'eat': 'rice'}, {'id': 2, 'name': 'Banana'}];
var res = ArrObj.find(({id}) => id === Obj1.id);
console.log(res);
You could also use the filter function like this:
let result = ArrObj.filter(obj => {
return obj.id == Obj1.id
})
Documentation is here: Array.prototype.filter()
all right!
you can also add array and get it by code :
var obj = '{ "name" : "amr" , "age" : "16"}';
var obj1 = JSON.parse(obj);
alert("yourname is : "+obj1.name+" , your age is "+obj1.age);
// it get name > amr and age > 16
it's very easy :)

JavaScript: How to Fetch a object from array of objects, given an id, without using for..in loop?

Let us assume that we have an array
var mRegions = [];
This array get's populated with following object
$.ajax(settings).done(function (response) {
for (var i in response.items[0].devices)
{
mRegions.push(
{
id: response.items[0].devices[i].id,
name: response.items[0].devices[i].name,
description: response.items[0].devices[i].description,
uid: response.items[0].devices[i].beacon.iBeacon.uid,
major: response.items[0].devices[i].beacon.iBeacon.major,
minor: response.items[0].devices[i].beacon.iBeacon.minor,
});
}
var myId = 'b1';
At some point of time, I need to get an object from this array of objects whose id matches with the given id (myID)
Is there a way to achieve this without a for...in loop?
Array.prototype.find(). Make sure you read the browser compatibility section.
myRegions.find(region => region.id === myId)
or the legacy version
myRegions.find(function(r){return r.id === myId})
let myRegions = [{
id: 'a1',
name: 'A 1'
}, {
id: 'a2',
name: 'A 2'
}, {
id: 'a3',
name: 'A 3'
}, {
id: 'b1',
name: 'B 1'
}, {
id: 'b2',
name: 'B 2'
}];
let myId = 'b1';
let pre = document.createElement('pre');
pre.textContent = JSON.stringify(myRegions.find(region => region.id === myId), null, ' ');
document.body.appendChild(pre);
If it is an option, you can use an object istead of an array, and set the keys as ids.
var mRegions = {};
$.ajax(settings).done(function (response) {
for (var i in response.items[0].devices) {
mRegions[response.items[0].devices[i].id] = {
id: response.items[0].devices[i].id,
name: response.items[0].devices[i].name,
description: response.items[0].devices[i].description,
uid: response.items[0].devices[i].beacon.iBeacon.uid,
major: response.items[0].devices[i].beacon.iBeacon.major,
minor: response.items[0].devices[i].beacon.iBeacon.minor,
};
}
});
Then access the values with the following notation:
var region = mRegions.theId
Or:
var myId = 123;
var region = mRegions[myId];
let array = [
{id: 1, name: 'Name1'},
{id: 3, name: 'Name3'},
{id: 5, name: 'Name5'},
{id: 7, name: 'Name7'}
];
let result = array.filter(function( obj ) {
return obj.id === 5;
});
Also consider .find() function from #Phil answer.
.filter definition:
The filter() method creates a new array with all elements that pass
the test implemented by the provided function.
.find definition:
The find() method returns a value in the array, if an element in the
array satisfies the provided testing function. Otherwise undefined is
returned.

How search two arrays and find if there is a match?

I have an array :
[{name:'blah',id:1},{name:'blah2',id:3}]
I have another array :
[{type:'blah',uid:3435},{type:'blah2',uid:3}]
I want to end up with :
[{newname:'blah2',uidid:3}]
You can see I want to match the two based on a mapping of id=uid. Really struggling to find a way to do this in js. I have underscore installed.
You could build a hash table with the first array and use it in the iteration of the second array.
var array1 = [{ name: 'blah', id: 1 }, { name: 'blah2', id: 3 }],
array2 = [{ type: 'blah', uid: 3435 }, { type: 'blah2', uid: 3 }],
hash = Object.create(null),
match = [];
array1.forEach(function (a) {
hash[a.id] = a;
});
array2.forEach(function (a) {
hash[a.uid] && match.push({ newname: a.type, uidid: a.uid });
});
console.log(match);
Since you are wanting an array with an object that uses different key names, something like this will work. It is also simple to read and to understand without any complex syntax or logic.
var arr1 = [{name: 'blah', id: 1}, {name: 'blah2', id: 3}];
var arr2 = [{type: 'blah', uid: 3435}, {type: 'blah2', uid: 3}];
var arr3 = [];
arr1.forEach(function(obj1, i) {
arr2.forEach(function(obj2) {
if (obj1.id == obj2.uid) {
arr3.push({newname: obj1.name, uidid: obj1.id})
}
})
});
console.log(arr3);

Categories

Resources