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.
Related
I've been tasked with creating an API connector between two systems. I needed to compare employees objects in SystemA and SystemB, then determine which employees would be new users, updating users, and users to be deleted in SystemB.
The goal is as follows:
Take an array of objects from SystemA and take an array of objects from SystemB. Then compare the two array of objects, and determine which objects need to be CREATED, UPDATED, and DELETED in SystemB.
If there are objects in SystemA's array that are not in SystemB's array, then those objects should be CREATED in SystemB system.
If there are objects in SystemA's array that are also in SystemB's array, then those objects in SystemB should be UPDATED.
If there are objects in SystemB's array that are not in SystemA's array, then those objects should be DELETED from SystemB's system.
This is what I came up with.
// SystemA
const objArray1 = [
{ id: "1", name: "John" },
{ id: "2", name: "Jack" },
{ id: "3", name: "Sam" },
{ id: "4", name: "Bill" },
];
// SystemB
const objArray2 = [
{ id: "1", name: "John" },
{ id: "3", name: "Sam" },
{ id: "5", name: "Bob" },
];
const array1IDs = objArray1.map((item) => {
return item.id
})
// Result: array1IDs = ["1", "2", "3", "4"];
const array2IDs = objArray2.map((item) => {
return item.id
})
// Result: array2IDs = ["1", "3", "5"];
// FIND SYNCED USERS
// Compare the id value of each item in objArray1 with each item of objArray2
// Return the ones that match.
const syncedUsers = objArray1.filter((item) => {
const found = objArray2.find((element) => element.id === item.id);
return found;
});
// FIND NEW USERS
// Filter through each item in objArray1.
// If array2IDs array doesn't include a value matching the id of the current item,
// then return the current item
const newUsers = objArray1.filter((item) => {
if (!array2IDs.includes(item.id)) {
return item;
}
});
// FIND USERS TO DELETE
// Filter through each item in objArray2.
// If array1IDs array doesn't include a value matching the id of the current item,
// then return the current item
const usersToDelete = objArray2.filter((item) => {
if (!array1IDs.includes(item.id)) {
return item;
}
});
// Log results (or work with resulting arrays)
console.log("Synced Users:", syncedUsers);
console.log("New Users:", newUsers);
console.log("Users to delete:", usersToDelete);
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))
I have an array of players objects like this :
var players = [{
id: "thisIsID1",
name: "William",
otherProps
},
{
id: "thisIsID2",
name: "Shakespeare",
otherProps
},
{
id: "thisIsID3",
name: "Lola",
otherProps
}]
And I have and array of their ID that has been shuffled, like so :
var shuffledIDs = ["thisIsID2", "thisIsID3", "thisIsID1"]
How can I sort the players var so the objects are in the same order as the corresponding IDs of shuffledIDs ?
Edit: different names just for the sake of making players different
If your data is short, then you can sort it with the following one-liner:
players = shuffledIDs.map(id => players.find(v => v.id == id))
Essentially, for every id in shuffledID, it finds the element in players with that id and puts it in the correct spot. However, this takes O(n^2) time so it might not scale well for larger data. If you want a faster method, you can maintain an object of IDs:
var ids = {};
players.forEach(v => ids[v.id] = v);
players = shuffledIDs.map(v => ids[v]);
You can achieve it using array .find() method:
var players = [{
id: "thisIsID1",
name: "William"
},
{
id: "thisIsID2",
name: "Shakespeare"
},
{
id: "thisIsID3",
name: "Lola"
}]
var shuffledIDs = ["thisIsID2", "thisIsID3", "thisIsID1"]
var result = shuffledIDs.map(x => players.find(p=>p.id === x))
console.log(result)
Create object with keys and values as index from shuffle array.
Use sort method and prioritize bases above shuffled indexes. This way should even the case of duplicate data in players.
var players = [
{
id: "thisIsID1",
name: "William"
},
{
id: "thisIsID2",
name: "Shakespeare"
},
{
id: "thisIsID3",
name: "Lola"
}
];
const shuffleIds = ["thisIsID2", "thisIsID3", "thisIsID1"];
const shuf_idx = Object.fromEntries(shuffleIds.map((x, i) => [x, i]));
players.sort((a, b) => shuf_idx[a.id] - shuf_idx[b.id]);
console.log(players);
With .map() and .find() where using index of the element:
const shuffledIDs = ["thisIsID2", "thisIsID3", "thisIsID1"];
const players = [{ id: "thisIsID1", name: "William" }, { id: "thisIsID2", name: "Shakespeare" }, { id: "thisIsID3", name: "Lola" }];
const result = players.map((e, i) => players.find(f => f.id === shuffledIDs[i]));
console.log(result);
I created a sample code to demo my problem, the actual data is much bigger
const arr = [{
id: 1
}, {
id: 2,
items: [{
id: 1
}]
}]
const target = 2
const nextIndex = 1
newArr = arr.map(o => o.id === target ? ({
...o,
items: [...o.items, {
id: 'new id'
}]
}) : o);
console.log(newArr);
How to insert {id: 'new id'} by index? Above code is appending onto items array. Assuming I have a click event, user can insert the position of {id: 'new id} by index, I can't use append as it doesn't replace existing object.
expected output
[{
id: 1
}, {
id: 2,
items: [{
id: 1
},{
id: 'something'
}]
Above code doesn't work, adding new item to items array without using index.
Try to pass index from onClick event
functionName = (i) => { //where i is index from onclick event
arr.map( o, index) => {
if(i === index)
{
const obj = { //object
id: 'new id'
}
arr[i].push(obj) // push object at given index from onClick
}
}
}
The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements
const target = 2;
int index = arr.findIndex(v => v.id == target);
if (index > -1) {
arr.splice(index, 1, {id: 'new id'}); // replace 1 with 0 if you just want to insert.
}
i want to access the id 'qwsa221' without using array index but am only able to reach and output all of the array elements not a specific element.
i have tried using filter but couldnt figure out how to use it properly.
let lists = {
def453ed: [
{
id: "qwsa221",
name: "Mind"
},
{
id: "jwkh245",
name: "Space"
}
]
};
Use Object.keys() to get all the keys of the object and check the values in the array elements using . notation
let lists = {
def453ed: [{
id: "qwsa221",
name: "Mind"
},
{
id: "jwkh245",
name: "Space"
}
]
};
Object.keys(lists).forEach(function(e) {
lists[e].forEach(function(x) {
if (x.id == 'qwsa221')
console.log(x)
})
})
You can use Object.Keys method to iterate through all of the keys present.
You can also use filter, if there are multiple existence of id qwsa221
let lists = {
def453ed: [
{
id: "qwsa221",
name: "Mind"
},
{
id: "jwkh245",
name: "Space"
}
]
};
let l = Object.keys(lists)
.map(d => lists[d]
.find(el => el.id === "qwsa221"))
console.log(l)
you can do it like this, using find
let lists = {
def453ed: [
{
id: "qwsa221",
name: "Mind"
},
{
id: "jwkh245",
name: "Space"
}
]
};
console.log(
lists.def453ed // first get the array
.find( // find return the first entry where the callback returns true
el => el.id === "qwsa221"
)
)
here's a corrected version of your filter :
let lists = {def453ed: [{id: "qwsa221",name: "Mind"},{id: "jwkh245",name: "Space"}]};
// what you've done
const badResult = lists.def453ed.filter(id => id === "qwsa221");
/*
here id is the whole object
{
id: "qwsa221",
name: "Mind"
}
*/
console.log(badResult)
// the correct way
const goodResult = lists.def453ed.filter(el => el.id === "qwsa221");
console.log(goodResult)
// filter returns an array so you need to actually get the first entry
console.log(goodResult[0])