I'm trying to group the objects for the users that have the same location and type value shown in the example below. What would be the best way to approach this?
const diabetics = [
{
type: 'type 1',
location: 'Boston'
email: 'person1#gmail.com'
},
{
type: 'type 2',
location: 'New York'
email: 'person2#gmail.com'
},
{
type: 'type 1',
location: 'Boston'
email: 'person3#gmail.com'
},
{
type: 'type 1',
location: 'Maine'
email: 'person4#gmail.com'
},
]
// expected output
const diabetics = [
{
type: 'type 1',
location: 'Boston'
email: [
'person1#gmail.com',
'person3#gmail.com'
]
},
{
type: 'type 2',
location: 'New York'
email: 'person2#gmail.com'
},
{
type: 'type 1',
location: 'Maine'
email: 'person4#gmail.com'
},
]
You could also get the result using Array.reduce(), creating groups using a key composed of type and location.
Once we have a map keyed on type and location we can use Array.values() to return the desired result:
const diabetics = [ { type: 'type 1', location: 'Boston', email: 'person1#gmail.com' }, { type: 'type 2', location: 'New York', email: 'person2#gmail.com' }, { type: 'type 1', location: 'Boston', email: 'person3#gmail.com' }, { type: 'type 1', location: 'Maine', email: 'person4#gmail.com' }, ]
const result = Object.values(diabetics.reduce ((acc, { type, location, email }) => {
// Create a grouping key, in this case using type and location...
const key = [type, location].join("-");
acc[key] ||= { type, location, email: [] };
acc[key].email.push(email);
return acc;
}, {}))
console.log('Result:', result);
Related
I have the following array object.
let reports = [
{
cc: 'BEL',
cn: 'Belgium',
entities: [
{
entityName: 'Company A',
address: 'some address'
},
{
entityName: 'Company B',
address: 'some address'
}
]
},
{
cc: 'LUX',
cn: 'Luxembourg',
entities: [
{
entityName: 'Company C',
address: 'some address'
}
]
}
];
I want to go through reports and create a new array with only the value of entityName how can I accomplish this?
The new array should look like ['Company A', 'Company B', 'Company C']. How can I accomplish this?
I tried doing: reports.map(e => e.entities.map(r => r.entityName)). However this returns:
[['Company A', 'Company B'], ['Company C']]
You can use .flat() on your result.
let reports = [
{
cc: 'BEL',
cn: 'Belgium',
entities: [
{
entityName: 'Company A',
address: 'some address'
},
{
entityName: 'Company B',
address: 'some address'
}
]
},
{
cc: 'LUX',
cn: 'Luxembourg',
entities: [
{
entityName: 'Company C',
address: 'some address'
}
]
}
];
const res = reports.map(e => e.entities.map(r => r.entityName)).flat();
console.log(res);
I'd do it like this where I first map entities, then flat them and finally return entityNames as a single array result:
let reports = [{
cc: 'BEL',
cn: 'Belgium',
entities: [{
entityName: 'Company A',
address: 'some address'
},
{
entityName: 'Company B',
address: 'some address'
}
]
},
{
cc: 'LUX',
cn: 'Luxembourg',
entities: [{
entityName: 'Company C',
address: 'some address'
}]
}
];
const flattenedEntities = reports
.map(({entities}) => entities)
.flat()
.map(({entityName}) => entityName);
console.log(flattenedEntities);
You can get simply by using for loop.
var reports = [
{
cc: 'BEL',
cn: 'Belgium',
entities: [
{
entityName: 'Company A',
address: 'some address'
},
{
entityName: 'Company B',
address: 'some address'
}
]
},
{
cc: 'LUX',
cn: 'Luxembourg',
entities: [
{
entityName: 'Company C',
address: 'some address'
}
]
}
];
var yourarray = [];
for (var j = 0; j < reports.length; j++) {
var reportentity = reports[j].entities;
for (var i = 0; i < reportentity.length; i++) {
yourarray.push(reportentity[i].entityName);
}
}
console.log(yourarray)
id like to create an new object "formattedCharacters" from the object data.
I need to capture every ID and filter the elements id, name, image, species, gender, location and status but I am unable to pass the data into the new object.
My idea was to pass the object to an array using object values, and then use for each to pass every element into my new array of objects, nevertheless I have been unable to do it.
Could you please help assesing why this isnt working and any tips on what should I try?
// Json data example
function getCharacters() {
const data = {
info: {
count: 671,
pages: 34,
next: 'https://rickandmortyapi.com/api/character?page=2',
prev: null,
},
results: [{
id: 1,
name: 'Rick Sanchez',
status: 'Alive',
species: 'Human',
type: '',
gender: 'Male',
origin: {
name: 'Earth (C-137)',
url: 'https://rickandmortyapi.com/api/location/1',
},
location: {
name: 'Earth (Replacement Dimension)',
url: 'https://rickandmortyapi.com/api/location/20',
},
image: 'https://rickandmortyapi.com/api/character/avatar/1.jpeg',
episode: [
'https://rickandmortyapi.com/api/episode/1',
'https://rickandmortyapi.com/api/episode/2',
],
url: 'https://rickandmortyapi.com/api/character/1',
created: '2017-11-04T18:48:46.250Z',
},
{
id: 2,
name: 'Morty Smith',
status: 'Alive',
species: 'Human',
type: '',
gender: 'Male',
origin: {
name: 'Earth (C-137)',
url: 'https://rickandmortyapi.com/api/location/1',
},
location: {
name: 'Earth (Replacement Dimension)',
url: 'https://rickandmortyapi.com/api/location/20',
},
image: 'https://rickandmortyapi.com/api/character/avatar/2.jpeg',
episode: [
'https://rickandmortyapi.com/api/episode/1',
'https://rickandmortyapi.com/api/episode/2',
......
// here is the problem
const formatedCharcters = data.results
formatedCharcters.forEach(character => {
return {
id: character.id
name: character.name
status: character.status
species: character.species
gender: character.gender
location: character.location.name
image: character.image
}
})
return formatedCharcters;
}
const characters = getCharacters();
You will want to use something like map instead
This is a simply change to your code:
formatedCharcters = data.results.map(character => {
Here's a guess of what you're trying to achieve. I think you're trying to map data into objects with a forEach loop. Sadly this is not possible with forEach , but rather with the map function instead. Let me know if this is what you wanted. I am willing to edit my answer depending on any other details.
const results = [{
id: 1,
name: 'Rick Sanchez',
status: 'Alive',
species: 'Human',
type: '',
gender: 'Male',
origin: {
name: 'Earth (C-137)',
url: 'https://rickandmortyapi.com/api/location/1',
},
location: {
name: 'Earth (Replacement Dimension)',
url: 'https://rickandmortyapi.com/api/location/20',
},
image: 'https://rickandmortyapi.com/api/character/avatar/1.jpeg',
episode: [
'https://rickandmortyapi.com/api/episode/1',
'https://rickandmortyapi.com/api/episode/2',
],
url: 'https://rickandmortyapi.com/api/character/1',
created: '2017-11-04T18:48:46.250Z',
},
{
id: 2,
name: 'Morty Smith',
status: 'Alive',
species: 'Human',
type: '',
gender: 'Male',
origin: {
name: 'Earth (C-137)',
url: 'https://rickandmortyapi.com/api/location/1',
},
location: {
name: 'Earth (Replacement Dimension)',
url: 'https://rickandmortyapi.com/api/location/20',
},
image: 'https://rickandmortyapi.com/api/character/avatar/2.jpeg',
episode: [
'https://rickandmortyapi.com/api/episode/1',
'https://rickandmortyapi.com/api/episode/2',
],
url: 'https://rickandmortyapi.com/api/character/1',
created: '2017-11-04T18:48:46.250Z',
}]
function getCharacters() {
const charachters = results.map(character => {
return {
id: character.id,
name: character.name,
status: character.status,
species: character.species,
gender: character.gender,
location: character.location.name,
image: character.image,
};
});
return charachters;
}
console.log(getCharacters());
I am not sure that I completely understand your question, but here is one way you could achieve the result you are probably looking for. I have kept the forEach loop in case there is a specific reason for keeping it:
// Json data example
function getCharacters() {
const data = {
info: {
count: 671,
pages: 34,
next: 'https://rickandmortyapi.com/api/character?page=2',
prev: null,
},
results: [
{
id: 1,
name: 'Rick Sanchez',
status: 'Alive',
species: 'Human',
type: '',
gender: 'Male',
origin: {
name: 'Earth (C-137)',
url: 'https://rickandmortyapi.com/api/location/1',
},
location: {
name: 'Earth (Replacement Dimension)',
url: 'https://rickandmortyapi.com/api/location/20',
},
image: 'https://rickandmortyapi.com/api/character/avatar/1.jpeg',
episode: [
'https://rickandmortyapi.com/api/episode/1',
'https://rickandmortyapi.com/api/episode/2',
],
url: 'https://rickandmortyapi.com/api/character/1',
created: '2017-11-04T18:48:46.250Z'
},
{
id: 2,
name: 'second name',
status: 'Alive',
species: 'Human',
type: '',
gender: 'Female',
origin: {
name: 'Mars???',
url: 'sample-url.com/sample/example',
},
location: {
name: 'Mars??? (Replacement Dimension)',
url: 'sample-url.com/sample/example',
},
image: 'sample-url.com/sample/example',
episode: [
'sample-url.com/sample/example',
'sample-url.com/sample/example',
],
url: 'sample-url.com/sample/example',
created: '2019-12-04T11:48:46.250Z'
}
]
}
// here is the problem
const formattedCharacters = data.results;
const character_array = [];
formattedCharacters.forEach(character=>{
//here instead of returning multiple times, just push value into an array
character_array.push({
id: character.id,
name: character.name,
status: character.status,
species: character.species,
gender: character.gender,
location: character.location.name,
image: character.image
});
})
return character_array;
}
const characters = getCharacters();
// therefore:
const character_1 = characters[0];
console.log(character_1);
The above would produce an array of all the elements inside of data.results with the values you need.
Hope that helped, AlphaHowl.
Is there a built in Javascript function or library to do the following:
const data = [
{ name: 'name1', type: 'type1' },
{ name: 'name2', type: 'type2' },
{ name: 'name3', type: 'type3' },
{ name: 'name4', type: 'type2' },
];
To search the following and return all objects where type = 'type2'
Something similar to data.findIndex((i) => i.type === 'type2') but returns all matches rather than first index?
Thanks
You are looking for Array.filter():
The filter() method creates a new array with all elements that pass
the test implemented by the provided function.
Example:
const data = [
{ name: 'name1', type: 'type1' },
{ name: 'name2', type: 'type2' },
{ name: 'name3', type: 'type3' },
{ name: 'name4', type: 'type2' },
]
const result = data.filter(o => o.type === 'type2')
console.log(result)
You can use filter()
const data = [
{ name: 'name1', type: 'type1' },
{ name: 'name2', type: 'type2' },
{ name: 'name3', type: 'type3' },
{ name: 'name4', type: 'type2' },
];
let res = data.filter(({type}) => type === "type2");
console.log(res)
I have an array of objects like this one:
[
{
name: 'John',
email: 'user#mail.com',
city: 'London',
type: 'CLIENT'
},
{
name: 'Steve',
email: 'stave#mail.com',
city: 'Rome',
type: 'USER'
},
{
name: 'Mark',
email: 'mark#mail.com',
city: 'Paris',
type: 'ADMIN'
}
]
I need to transform it into something like this:
{
CLIENT: {
name: 'John',
email: 'user#mail.com',
city: 'London'
},
USER: {
name: 'Steve',
email: 'stave#mail.com',
city: 'Rome',
},
ADMIN: {
name: 'Mark',
email: 'mark#mail.com',
city: 'Paris',
type: 'ADMIN'
}
}
What's the best approach?
Thank you
Use Array#reduce with a simple object destructuring to get your desired result:
const data = [{
name: 'John',
email: 'user#mail.com',
city: 'London',
type: 'CLIENT'
},
{
name: 'Steve',
email: 'stave#mail.com',
city: 'Rome',
type: 'USER'
},
{
name: 'Mark',
email: 'mark#mail.com',
city: 'Paris',
type: 'ADMIN'
}
];
const result = data.reduce((acc, { type, ...obj }) => {
acc[type] = obj;
return acc;
}, {})
console.log(result);
With upcoming object rest properties in ES2018/ES9 or with BABEL, you could take the type property and use the rest properties for a new object for assignment.
var array = [{ name: 'John', email: 'user#mail.com', city: 'London', type: 'CLIENT' }, { name: 'Steve', email: 'stave#mail.com', city: 'Rome', type: 'USER' }, { name: 'Mark', email: 'mark#mail.com', city: 'Paris', type: 'ADMIN' }],
object = Object.assign(...array.map(({ type, ...o }) => ({ [type]: o })));
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could also use reduce() and Object.assign() to get the required result.
DEMO
var arr = [{ name: 'John', email: 'user#mail.com', city: 'London', type: 'CLIENT' }, { name: 'Steve', email: 'stave#mail.com', city: 'Rome', type: 'USER' }, { name: 'Mark', email: 'mark#mail.com', city: 'Paris', type: 'ADMIN' }];
console.log(arr.reduce((r,{type,...rest})=>Object.assign(r,{[type]:rest}),{}));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I am can't figure out how to do this without iterating over the array three times.
I am looking to transform an array of job listings that look like this:
const jobs = [
{
title: 'Manager',
department: 'Retail',
location: 'New York'
},
{
title: 'Customer Service Rep',
department: 'Corporate',
location: 'Washington D.C.'
},
{
title: 'Clerk',
department: 'Retail',
location: 'New York'
},
...
];
Into an object of unique departments with associated jobs:
const deps = {
'Corporate': [
{
title: 'Customer Service Rep',
department: 'Corporate',
location: 'Washington D.C.'
},
],
'Retail': [
{
title: 'Manager',
department: 'Retail',
location: 'New York'
},
{
title: 'Clerk',
department: 'Retail',
location: 'New York'
},
],
};
Is _map my best bet here? Is there a more eloquent way of doing this?
You can use array#reduce to group jobs based on department.
const jobs = [ { title: 'Manager', department: 'Retail', location: 'New York' }, { title: 'Customer Service Rep', department: 'Corporate', location: 'Washington D.C.' }, { title: 'Clerk', department: 'Retail', location: 'New York' }],
deps = jobs.reduce((r,job) => {
r[job.department] = r[job.department] || [];
r[job.department].push(job);
return r;
},{});
console.log(deps);
You can use _.groupBy
const jobs = [ { title: 'Manager', department: 'Retail', location: 'New York' }, { title: 'Customer Service Rep', department: 'Corporate', location: 'Washington D.C.' }, { title: 'Clerk', department: 'Retail', location: 'New York' }],
deps = _.groupBy(jobs, 'department');
console.log(deps);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>