This question already has answers here:
How to get the difference between two arrays of objects in JavaScript
(22 answers)
Array.includes() to find object in array [duplicate]
(8 answers)
Closed 11 months ago.
I have an array of available items:
const items = [{id: 1, title: Item 1}, {id: 2, title: Item 2}, {id: 3, title: Item 3}]
and an array of items that my user has purchased:
const purchasedItems = [{id: 1, title: Item 1}, {id: 2, title: Item 2}]
I want to display an array of items that are still available to them to purchase that they haven't bought yet, i.e. just item 3 in this case. So I want an array returned with just Item 3 in it.
I have tried:
const availableItems = items.filter(
(item) => !purchasedItems.includes(item)
)
However this just returns a list of all the items again.
Think I must be missing something quite obvious, any help appreciated!
includes won't work here because it will only compare the items with a strict equality (as in item1 === item2). It will only works if your items are the same objects with the same reference.
A little example:
const obj1 = { test: 1 };
const obj2 = obj1;
const obj3 = { test: 1 };
console.log(obj1 === obj2); // true
console.log(obj1 === obj3); // false
So, in your case, you have to do a more complex work in your filter function:
const availableItems = items.filter(item1 => !purchasedItems.some(item2 => item1.id === item2.id));
Use findIndex() instead of includes
const items = [{ id: 1, title: 'Item 1' }, { id: 2, title: 'Item 2' }, { id: 3, title: 'Item 3' }]
const purchasedItems = [{ id: 1, title: 'Item 1' }, { id: 2, title: 'Item 2' }]
const availableItems = items.filter((item) => (purchasedItems.findIndex(purchasedItem => purchasedItem.id === item.id) == -1))
console.log(availableItems)
Related
I have an array of objects that have specific IDs and another second array of objects that also have specified IDs. I want to delete objects from the first array that have the same ID as objects in the second array. How can I do it?
Is that what you're trying to do?
let arr1 = [{
id: 0,
name: 'x'
}, {
id: 1,
name: 'y'
}, {
id: 2,
name: 'z'
}];
const arr2 = [{
id: 0,
name: 'x'
}];
arr1 = arr1.filter(element => !arr2.find(el => el.id === element.id));
console.log(arr1);
Here is a link that seems to fit what you are trying to accomplish.
How to merge two arrays in JavaScript and de-duplicate items
You can simply achieve this requirement with the help of Array.filter() along with the Array.includes() method.
Live Demo :
const arr1 = [{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}, {
id: 5
}];
const arr2 = [{
id: 2
}, {
id: 3
}, {
id: 5
}];
const res = arr1.filter(obj => !arr2.map(({ id }) => id).includes(obj.id));
console.log(res);
This question already has answers here:
Merge two array of objects based on a key
(23 answers)
Closed last year.
I have two Objects one of them has the Store Name and the other object has the Price for an item along with the Store ID on both objects. Such as;
obj1 = [
{id: 1,name: "Store1"},
{id: 2,name: "Store2"},
{id: 3,name: "Store3"}
];
obj2= [
{ id: 1, price: 100 },
{ id: 2, price: 200 },
{ id: 3, price: 300 }
];
What I want to achieve is that compare obj1 id with obj2 id if they are the same get the price and the store name from the same id. What is the best way to achieve this? I have been trying to use Array.map or filter but can't really make it work. Thank you!
You can use map & find
const obj1 = [{
id: 1,
name: "Store1"
},
{
id: 2,
name: "Store2"
},
{
id: 3,
name: "Store3"
},
{
id: 4,
name: "Store3"
}
];
const obj2 = [{
id: 1,
price: 100
},
{
id: 2,
price: 200
},
{
id: 3,
price: 300
}
];
const newData = obj1.map((item, index) => {
return {
...item,
// if the item exist in obj2 then get the price else assign empty string
price: obj2.find(elem => elem.id === item.id) ? .price || ''
}
});
console.log(newData)
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
I have two object arrays and want to find the items that are missing in the second array but are part of the first array,basically array1-array2.I tried to use filter but I'm unable to get the desired result.Please help.Thanks in advance.
Here is the code:
testData=[
{id: 0, name: "policy001"},
{id: 2, name: "policy002"}];
sourceData= [
{id: 0, name: "policy001"},
{id: 2, name: "policy002"},
{id: 3, name: "policy003"},
{id: 4, name: "policy004"},
{id: 5, name: "policy005"},
];
let missing = sourceData.filter(item => testData.indexOf(item) < 0);
console.log("Miss")
console.log(missing )//Returns the sourceData instead of diff.
Try findIndex():
The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise, it returns -1, indicating that no element passed the test.
testData = [{
id: 0,
name: "policy001"
},
{
id: 2,
name: "policy002"
}
];
sourceData = [{
id: 0,
name: "policy001"
},
{
id: 2,
name: "policy002"
},
{
id: 3,
name: "policy003"
},
{
id: 4,
name: "policy004"
},
{
id: 5,
name: "policy005"
},
];
console.log(sourceData.filter(item => testData.findIndex(x => x.id == item.id) < 0))
The reason your code did not work is that object inside array are "addresses" to the objects. So of course the indexOf did not work
try below:
let missing = sourceData.filter(a => !testData.find(b => a.id === b.id));
You're getting this undesired behavior because what you're doing in your filter is comparing the items' references rather than their values. if you want to compare that those objects are actually identical in values (because they have different references), you need to do the following:
let missing = sourceData.filter(sourceItem =>
testData.every(testItem =>
testItem.id !== sourceItem.id && testItem.name !== sourceItem.name
)
)
this means - filter out those element of sourceData, for which none of the elements in testData has the same id or name. They are "missing".
This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 6 years ago.
I have an array of objects:
[
{
id: 1,
name: 'bill'
},
{
id: 2,
name: 'ted'
}
]
Looking for a simple one-liner to return:
[
{
value: 1,
text: 'bill'
},
{
value: 2,
text: 'ted'
}
]
So I can easily pump them into a react dropdown with the proper keys.
I feel like this simple solution should work, but I'm getting invalid syntax errors:
this.props.people.map(person => { value: person.id, text: person.name })
You just need to wrap object in ()
var arr = [{
id: 1,
name: 'bill'
}, {
id: 2,
name: 'ted'
}]
var result = arr.map(person => ({ value: person.id, text: person.name }));
console.log(result)