Given the following data set:
const users = {
"1": { id: "1", name: "Alex" },
"2": { id: "2", name: "John" },
"3": { id: "3", name: "Paul" }
};
const memberships = [
{ userId: "1", groupId: "1" },
{ userId: "2", groupId: "2" },
{ userId: "3", groupId: "1" }
];
What is an effective way to achieve following desired result?
const usersByGroupId = {
"1": [{ id: "1", name: "Alex" }, { id: "3", name: "Paul" }],
"2": [{ id: "2", name: "John" }]
}
I came up with the following (using Lodash):
const usersByGroupId = mapValues(
groupBy(memberships, "groupId"),
memberships => memberships.map(membership => users[membership.userId])
);
I'm not that familiar with big O notation, but I can imagine the performance of the above solution is pretty terrible on large sets. Any suggestions for improvement?
You don't really need lodash — you can do this in one step with reduce(). Just check if the key exists, if so push, if not set a new array and push. It just requires one iteration of the membership array and for each a lookup in the users object (which is more-or-less constant time) making this a linear time operation.
const users = {"1": { id: "1", name: "Alex" },"2": { id: "2", name: "John" },"3": { id: "3", name: "Paul" }};
const memberships = [{ userId: "1", groupId: "1" },{ userId: "2", groupId: "2" },{ userId: "3", groupId: "1" }];
let groups = memberships.reduce((obj, {userId, groupId}) => {
(obj[groupId] || (obj[groupId] = []) ).push(users[userId])
return obj
}, {})
console.log(groups)
Related
So I am trying to merge 2 arrays of objects by ID-s (ID and AUTOMOBIL) with this code I only push last array of objects(OPREMA). Someone have any idea how can I get all of them in the spot they should be?
So when ID in a1 is == 1 I need all of OPREMA in a2 witch AUTOMOBIL is equal to 1 to save it together it a1, but with this code it's only saving last one.
const a1 = [
{ ID: "2", TIP: "A3", VRSTA: "Limousine", $$hashKey: "object:3" },
{ ID: "1", TIP: "A5", VRSTA: "Coupe", $$hashKey: "object:7" },
];
const a2 = [
{
AUTOMOBIL: "1",
OPREMA: {
ID: "5",
NAZIV_OPREME: "Automatski",
VRSTA_OPREME: "2",
CIJENA: "15000",
OPIS: "Automatski mjenjač",
},
},
{
AUTOMOBIL: "1",
OPREMA: {
ID: "3",
NAZIV_OPREME: "Benzin",
VRSTA_OPREME: "1",
CIJENA: "7000",
OPIS: "Gorivo benzin",
},
},
{
AUTOMOBIL: "1",
OPREMA: {
ID: "19",
NAZIV_OPREME: "1.0",
VRSTA_OPREME: "5",
CIJENA: "7000",
OPIS: "potrosnja 3-6l",
},
},
{
AUTOMOBIL: "1",
OPREMA: {
ID: "11",
NAZIV_OPREME: "Sportback",
VRSTA_OPREME: "3",
CIJENA: "70000",
OPIS: "sportski izgled šasije",
},
},
{
AUTOMOBIL: "1",
OPREMA: {
ID: "8",
NAZIV_OPREME: "Quattro",
VRSTA_OPREME: "4",
CIJENA: "15000",
OPIS: "Pogon na sve kotače",
},
},
];
const a3 = a1.map(t1 => ({ ...t1, ...a2.find(t2 => t2.AUTOMOBIL === t1.ID) }));
//RESULT OF a3
console.log(a3);
In your question you never specified how exactly you want the elements of a2 to be saved in the a1 element. I'm assuming that you need them as a array under the OPREMA property. Your code was pretty close but instead of find you needed to use filter to keep all elements that match.
const a3 = a1.map(t1 => {
const matchingElements = a2.filter(t2 => t2.AUTOMOBIL === t1.ID);
return ({...t1, OPREMA: matchingElements.map(({ OPREMA }) => OPREMA) });
});
Given the data below, I have two select lists, the first select list is to display the name of each person... the second select list is two display the name of the children of the selected person. Using lodash what is the easiest way to do this?
const people = [{
id: "1",
name: "bob",
gender: "male",
children: [{
id: "1",
name: "sarah"
}]
},
{
id: "2",
name: "tom",
gender: "male",
children: [{
id: "1",
name: "lisa"
}]
},
{
id: "3",
name: "sue",
gender: "female",
children: [{
id: "1",
name: "larry"
}]
}
]
Please find the solution as below:
import map from "lodash/map";
import partialRight from "lodash/partialRight";
import pick from "lodash/pick";
import find from "lodash/find";
const test = [
{
id: "2",
name: "tom",
gender: "male",
children: [
{
id: "1",
name: "lisa"
}
]
},
{
id: "3",
name: "sue",
gender: "female",
children: [
{
id: "1",
name: "larry"
}
]
}
];
// Person selection list
const persons = map(test, partialRight(pick, ["id", "name", "gender"]));
// Replace selected person value in `persons[0]`.
const childrens = find(test, item => item.id === persons[0].id).children;
Basically, I want to flatten an array inside of an object with Javascript (preferably ES6). I'm actually not sure if this is even an issue of flattening, I just want a good way to make this change.
I want to go from this:
{
id: "123",
name: "test",
history: [
{
id: "456",
name: "test2"
},
{
id: "789",
name: "test3"
}
]
}
To this...
{
id: "123",
name: "test"
},
{
id: "456",
name: "test2"
},
{
id: "789",
name: "test3"
}
Essentially in the original object, I have a "history" property that related to that specific object. Any ideas?
You can use destructuring and rest syntax, to separate history and the 1st object, and then combine them to a single array with spread or concat.
const { history, ...obj1 } = {"id":"123","name":"test","history":[{"id":"456","name":"test2"},{"id":"789","name":"test3"}]}
const result = [obj1, ...history]
console.log(result)
try this:
const data = {
"id": "123",
"name": "test",
"history": [
{
"id": "456",
"name": "test2"
},
{
"id": "789",
"name": "test3"
}
]
}
const {id, name, history} = data ;
const result = [{id, name} , ...history];
console.log(result);
I have these two arrays:
main:
[
{ id: "1"},
{ id: "2"},
{ id: "3"}
]
filtered:
[
{ id: "80", link_id: "1"},
{ id: "50", link_id: null},
{ id: "67", link_id: "3"}
]
I need to get the items of main which have as id those contained in filtered with the property: link_id, I tried with:
main.filter(x => filtered.includes(x.id));
the problem is that this will return null, and also this doesn't allow me to check if link_id is null
var main = [{
id: "1"
},
{
id: "2"
},
{
id: "3"
}
],
filtered = [{
id: "80",
link_id: "1"
},
{
id: "50",
link_id: null
},
{
id: "67",
link_id: "3"
}
],
result = main.filter(x =>
filtered.includes(x.id)
);
console.log(result)
Try with some() method
var main = [
{ id: "1"},
{ id: "2"},
{ id: "3"}
]
var filtered = [
{ id: "80", link_id: "1"},
{ id: "50", link_id: null},
{ id: "67", link_id: "3"}
]
console.log(main.filter(x => filtered.some(item => item.link_id === x.id) ));
you are close, basically you need to check in each item of the filtered array.
includes is more for a plain object as the documentation states.
check the snippet below, you can use findIndex, find or some to get if the element exist on the filtered array.
const main = [{
id: "1"
},
{
id: "2"
},
{
id: "3"
}
]
const filtered = [{
id: "80",
link_id: "1"
},
{
id: "50",
link_id: null
},
{
id: "67",
link_id: "3"
}
]
const resultFindIndex = main.filter(item => -1 !== filtered.findIndex(filteredItem => item.id === filteredItem.link_id))
const resultFind = main.filter(item => filtered.find(filteredItem => item.id === filteredItem.link_id))
const resultSome = main.filter(item => filtered.some(filteredItem => item.id === filteredItem.link_id))
console.log(resultFindIndex)
console.log(resultFind)
console.log(resultSome)
Hello suppose I have the following array:
let array = [
{
id: "1",
name: "name",
categories: [
{
subid: "10",
name: "name",
},
{
subid: "11",
name: "name",
}
]
},
{
id: "2",
name: "name",
categories: [
{
subid: "20",
name: "name",
},
{
subid: "21",
name: "name",
}
]
}
]
My goal is to take the id of each of the objects and add it to the inner array categories. So it would look like this:
let array = [
{
id: "1",
name: "name",
categories: [
{
subid: "10",
name: "name",
id: "1"
},
{
subid: "11",
name: "name",
id: "1"
}
]
},
{
id: "2",
name: "name",
categories: [
{
subid: "20",
name: "name",
id: "2"
},
{
subid: "21",
name: "name",
id: "2"
}
]
}
]
Here is what I have so far:
array.map(x => (x.id)) // returns new array of ids
// add these into the categories
Can someone help me figure this out using map? If map cant be used I think for each will work as well
With map method and spread syntax inside object you could do this.
let array = [{"id":"1","name":"name","categories":[{"subid":"10","name":"name"},{"subid":"11","name":"name"}]},{"id":"2","name":"name","categories":[{"subid":"20","name":"name"},{"subid":"21","name":"name"}]}]
let result = array.map(({id, categories, ...rest}) => ({
...rest, id, categories: categories.map((o) => ({...o, id}))
}))
console.log(result)
You can use Array.forEach() to iterate over the array and then use Array.map() on categories array to add the id prop to all its objects:
let array = [ { id: "1", name: "name", categories: [ { subid: "10", name: "name", }, { subid: "11", name: "name", } ] }, { id: "2", name: "name", categories: [ { subid: "20", name: "name", }, { subid: "21", name: "name", } ] } ];
array.forEach((o)=>{
o.categories = o.categories.map(cat=>Object.assign({},cat,{id : o.id}));
});
console.log(array);
What about nested map?
let arr = [
{
id: "1",
name: "name",
categories: [
{
subid: "10",
name: "name",
},
{
subid: "11",
name: "name",
}
]
},
{
id: "2",
name: "name",
categories: [
{
subid: "20",
name: "name",
},
{
subid: "21",
name: "name",
}
]
}
]
arr.map(x=>{
x.categories.map(y => {
y.id = x.id
})
})
console.log(arr)
You need to map all arrays with copied properties to get a new independent data with a new property.
let array = [{ id: "1", name: "name", categories: [{ subid: "10", name: "name", }, { subid: "11", name: "name", }] }, { id: "2", name: "name", categories: [{ subid: "20", name: "name", }, { subid: "21", name: "name", }] }],
updated = array.map(o => Object.assign(
{},
o,
{ categories: o.categories.map(p => Object.assign({}, p, { id: o.id })) }
));
console.log(updated);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using each of Jquery should do the job.
$.each(array,function(index,item){item.categories.id = item.id;});
Thanks.