I'm trying to iterate over an array of objects that looks like this:
const arr = [{
id: 1,
name: "John",
storeName: "Amazon",
price: 100,
isRecieved: false,
deliveryDate: some date
}, ....]
I'm iterating over the array with product ID that I received from the user, finding the relevant item according to it's id and changing the key "isRecieved" from false to true.
This is my code:
const filterReceivedProduct = (list, id) => {
const changeReceivedState = list.filter((item) => {
return item.id === id ? **item[isRecieved]** = true : item;
})
return changeReceivedState
}
But when I'm trying to access the object using bracket notation it return the value (in this case 'false') and I can't change the value to true..
What I'm doing wrong?
You don't need to use .filter() here. The filter method is for removing elements from an array. What you want to do is map each element/object to a new object, which has all the properties from the old object, containing an updated isRecieved property. To create a new object with all the properties of the old object, you can spread the properties and values from the old object into a new one ({...item}). You can then update the isRecived based on your whether the item id matched the id passed into your function:
const arr = [{
id: 1,
name: "John",
storeName: "Amazon",
price: 100,
isRecieved: false,
deliveryDate: 'some date'
}, {
id: 2,
name: "Alex",
storeName: "Apple",
price: 200,
isRecieved: false,
deliveryDate: 'some date2'
}];
const filterReceivedProduct = (list, id) =>
list.map(item => ({
...item,
isRecieved: item.id === id // sets isRecieved to true or false based on the equalty comparison
}));
const res = filterReceivedProduct(arr, 1);
console.log(res);
By creating a new object within the .map() callback, you're never mutating the original objects in your arr, treating everything as immutable.
Here filter make no sense. Filter use to filter some array based on condition. If you just want to change some property of an object inside array then use map for this purpose.
See below example.
const arr = [{
id: 1,
name: "John",
storeName: "Amazon",
price: 100,
isRecieved: false,
deliveryDate: 'some date'
}, {
id: 2,
name: "Doe",
storeName: "Amazon",
price: 100,
isRecieved: false,
deliveryDate: 'some date'
}];
filterReceivedProduct = (list, id) => {
return list.map(item => {
if(item.id === id) {
item.isRecieved = true;
}
return item;
});
}
console.log(filterReceivedProduct(arr, 1))
Related
Hey guys is there a way i can retrieve the last unique object in an array
in the code below the id at the first and second index are the same is there a way i can retrieve the last occurrence of the id with the corresponding object
0: {id: 'tra.528555295', name: 'heart'}
1: {id: 'tra.528555295', name: 'heart-outline'}
2: {id: 'tra.528555301', name: 'heart'}
3: {id: 'tra.528555301', name: 'heart-outline'}
You need to iterate through the entire array and keep track of the "last" object with that unique ID found.
Here's one way you can do it using Array.prototype.reduce to iterate through the array and keep track of the "last" ID found, then pulling values with unique IDs using Object.values:
const arr = [
{ id: "tra.528555295", name: "heart" },
{ id: "tra.528555295", name: "heart-outline" },
{ id: "tra.528555301", name: "heart" },
{ id: "tra.528555301", name: "heart-outline" }
];
const result = Object.values(
arr.reduce((accumulator, item) => {
const { id, ...rest } = item;
return {
...accumulator,
[id]: { id, ...rest }
};
}, {})
);
console.log(result);
If you can provide the id I suggest:
const findLastElementOfId = (arr, id) => {
return arr.filter(object => object.id === id).at(-1)
}
filter the array for the objects with the id you are looking for and return the last one.
I have something like this:
items: { _id: number; place: SomeAddressClassDto }[] = [];
sessionItem: { _id: number; place: SomeAddressClassDto };
createAddressList() {
this.service.getWorkingPlaces().subscribe((items) => {
this.items = items;
this.sessionItem = {
place: JSON.parse(sessionStorage.getItem('currentPlace')),
_id: this.items.length,
};
this.items.push(this.sessionItem);
// _.uniqBy(this.items, 'place')
const idx = items.findIndex((item) => this.service.comparePlaces(item.place,
this.service.getCurrentWorkingPlace()));
if (idx !== -1) this.radiobox.option = `${idx}`;
});
}
I am trying to remove any duplicates from 'items' array using the method _uniqBy, but it isn't working. I think it's because for this items._id are always different but items.place could be equal and if are I would like to get rid of this.
Maybe better way is to check is the same items.place is already in that array, but no idea how to do this.
EDIT:
To be more specify, items looks like this:
0: place: {name, street, city, etc...}
_id: 0
So it is possible to have very similar object whitch is differnet only by one property in place{}
I would suggest using the _id to determine if the value is unique. If you use place the value may always be unique since they could be different instances of the same class.(I can't tell from your code if this is the case)
createAddressList() {
this.service.getWorkingPlaces().subscribe((items) => {
this.items = items;
this.sessionItem = {
place: JSON.parse(sessionStorage.getItem('currentPlace')),
_id: this.items.length,
};
this.items.push(this.sessionItem);
_.uniqBy(this.items, '_id');
const idx = items.findIndex((item) => this.service.comparePlaces(item.place, this.service.getCurrentWorkingPlace()));
if (idx !== -1) {
this.radiobox.option = `${idx}`;
}
});
}
Alternately, you could use a property from inside place to determine if they are unique like this:
_.uniqBy(this.items, (x) => x.place && x.place.someOtherPropertyInsideOfPlace);
You can use Array.Prototype.reduce() and Array.prototype.find() to create an array that has no duplicates based on the place property.
As an example:
const test = [
{ _id: 1, place: 'a' },
{ _id: 2, place: 'a' },
{ _id: 3, place: 'a' },
{ _id: 4, place: 'b' },
{ _id: 5, place: 'c' },
]
const noDups = test.reduce((accum, current)=> {
if(!accum.find(item => item.place === current.place))
accum.push(current)
return accum
}, [])
console.log(noDups)
reduce() will create a new array (in this case, the accum variable is being initialized as an empty array), but only add new items in the new array if the .place property is unique, if it doesn't already find an item with the same .place property
declaring a simple object array with id and place properties.
Removing duplicates by javascript filter function.
filter function will remove the objects from array whose place is paris.
var arr = [{
_id: 1,
place: 'paris'
},
{
_id: 2,
place: 'tokyo'
},
{
_id: 3,
place: 'ontario'
},
{
_id: 4,
place: 'paris'
},
{
_id: 5,
place: 'karachi'
},
{
_id: 6,
place: 'paris'
},
{
_id: 7,
place: 'new york'
}
];
var newArray = arr.filter((self, item, index) => index.findIndex(t => (t.place === self.place)) === item);
console.log(newArray);
I am trying to use .map() and ES6 syntax to return a truncated version of each object in my array. I can do this to get one value from the original object passed on:
return dbJobs.map(job =>
job.data.modType
);
But how would I use ES6 syntax to handle taking an array of objects where each object looks like this:
{
id: 123,
name: "name value",
data: {
modType: "report",
category: "value"
}
}
... and return an array of objects where each object has two properties from the original objects, like this:
{
name: "name value",
modType: "report"
}
You could use a destructuring and map objects with short hand properties.
var dbJobs = [{ id: 123, name: "name value", data: { modType: "report", category: "value" } }],
result = dbJobs.map(({ name, data: { modType } }) => ({ name, modType }));
console.log(result);
So with Array.prototype.map() you can create a new structure based on its function's return value.
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
Think about the following:
const array = [{
id: 123,
name: "name value",
data: {
modType: "report",
category: "value"
}
}];
const result = array.map(e => {
return {
name: e.name,
modeType: e.data.modType
}
});
console.log(result);
Or the same with destructuring:
const array = [{
id: 123,
name: "name value",
data: {
modType: "report",
category: "value"
}
}];
const result = array.map(({name, data: {modType}}) => {
return {
name,
modType
}
});
console.log(result);
I hope that helps!
I believe this will do what you need:
let obj = [{
id: 123,
name: "name value",
data: {
modType: "report",
category: "value"
}
}];
let res = obj.map(item => {
return {
modType: item.data.modType,
category: item.data.category
}
});
console.log(res);
You can try this simple js code
arr = arr.map(item => {
const ob = {} // create temporary object
ob.name = item.name; // asign props from array object
ob.modType = item.data.modType; // asign props from array object
return ob // just return create object
})
With Javascript how can I get the id of each object in this kind of object:
array = [
{ active: false, defaultTag:true, id: '507f191e810c19729de860ea', title: 'one' },
{ active: false, defaultTag:true, id: '507f191e810c19722de860ea', title: 'two' }
];
I need to fetch the id in order to check if the item already exists in the array whe a use intent to save the same object again.
Best regards
Americo
here you can get array of unique ids
var unique = [],
tmp, i = 0;
while(i < array.length){
unique.indexOf(tmp = array[i++].id) > -1 ? array.pop(i--) : unique.push(tmp)
}
console.log(unique);
Gather all your items under one object using Array.reduce. This will filter out duplicates
Use Object.values to get the values inside your object. The returned value is the filtered array
const array = [
{ active: false, defaultTag:true, id: '507f191e810c19729de860ea', title: 'duplicateOne' },
{ active: false, defaultTag:true, id: '507f191e810c19729de860ea', title: 'one' },
{ active: false, defaultTag:true, id: '507f191e810c19722de860ea', title: 'two' }
];
const removeDupsById = arr => Object.values(
arr.reduce((a, c) => ({...a, [c.id]: c}), {})
);
console.log(removeDupsById(array));
I have a plain JavaScript array of objects, say e.g.
const drawings = [
{
name: "Foo",
category: "widget"
},
{
name: "Bar",
category: "widget"
},
{
name: "Bar",
category: "fidget"
},
]
etc, where both the name and category have duplicates. What I want to end up with is essentially a list of objects (this is to meet the interface for a 3rd party library), where each object represents a name, and then for each category there is a property that is either true or false, depending on the original list. So for the example the output would be:
const output = [
{
name: "Foo",
widget: true,
fidget: false
},
{
{
name: "Bar",
widget: true,
fidget: true
},
]
I would first go through and make an object of your categories with the categories as keys and default values as false.
Then you can assign this to each object and set the correct keys to true as you go through.
const drawings = [{name: "Foo",category: "widget"},{name: "Bar",category: "widget"},{name: "Bar",category: "fidget"},]
// make category object where everything is false
let category_obj = drawings.reduce((a, item) => (a[item.category] = false, a), {})
let output = drawings.reduce((a, {name, category}) => {
// assign cat
if (!a.hasOwnProperty(name)) a[name] = Object.assign({}, {name}, category_obj)
// set to true if the correct category
a[name][category] = true
return a
}, {})
// the above makes an object, but you only want the array of values
console.log(Object.values(output))
If you already know the categories or if you have infered them as you suggested, you could use Array.reduce() like such:
drawings.reduce(function(acc, curr) {
if (!acc.some(elt => elt.name === curr.name)) {
acc.push({name: curr.name, widget: false, fidget: false})
}
const i = acc.findIndex(elt => elt.name === curr.name)
acc[i][curr.category] = true
return acc
}, [])