Related
Let's say I have an array of objects like:
flattenedObjects = [
{name: 'Bill', city: 1},
{name: 'Guillermo', city: 1},
{name: 'Wilhem', city: 1},
{name: 'William', city: 1},
{name: 'Nick', city: 2},
{name: 'Nicolas', city: 2},
{name: 'Nicholas', city: 2},
{name: 'Rick', city: 3}
]
I want to create individual arrays of objects grouped by "city". In the code, I will also deconstruct each object so that the final output will be:
boston = ['Bill', 'Guillermo', 'Wilhelm', 'William']
miami = ['Nick', 'Nickolas', 'Nicholas']
london = ['Rick']
I am having difficulties creating the grouped array of objects.
I can do it with one single object, as such:
let boston = flattenedObjects.filter(function (obj) {
return obj.city == 1;
});
What I was thinking of doing was to take a iterate through an object and filtering dynamically, like so:
let cities = {
boston: 1,
miami: 2,
london: 3
}
And then trying something like:
let newObj = flattenedObjects.filter(function (x) {
let obj = {};
Object.entries(cities).forEach(([key, value]) => {
obj["name"] = `${key}`;
obj["city"] = x.city == `${value}`;
return obj;
});
});
This isn't consoling what is expected. It's just an array of objects very similar to the "obj" up above.
let flattenedObjects = [
{name: 'Bill',city: 1},
{name: 'Guillermo',city: 1},
{name: 'Wilhem',city: 1},
{name: 'William',city: 1},
{name: 'Nick',city: 2},
{name: 'Nicolas',city: 2},
{name: 'Nicholas',city: 2},
{name: 'Rick',city: 3}
];
let cities = {
boston: 1,
miami: 2,
london: 3
}
let data = {}
for (const [key, value] of Object.entries(cities)) {
data[key] = flattenedObjects.filter(p => p.city === value).map(e => e.name);
}
console.log(data)
Create a reverse map of city code to city name, O(1) constant time lookups.
Reduce the flattenedObjects array into an object using the city name as a key and generate an array fo the names, O(n) linear access.
const flattenedObjects = [
{ name: "Bill", city: 1 },
{ name: "Guillermo", city: 1 },
{ name: "Wilhem", city: 1 },
{ name: "William", city: 1 },
{ name: "Nick", city: 2 },
{ name: "Nicolas", city: 2 },
{ name: "Nicholas", city: 2 },
{ name: "Rick", city: 3 }
];
const cities = {
boston: 1,
miami: 2,
london: 3
};
const citiesByCode = Object.fromEntries(
Object.entries(cities).map(([city, code]) => [code, city])
);
const groupedResult = flattenedObjects.reduce((groups, current) => {
const cityCode = citiesByCode[current.city];
if (!groups[cityCode]) groups[cityCode] = [];
groups[cityCode].push(current.name);
return groups;
}, {});
console.log(groupedResult);
You could use a reduce statement to reduce the flattenedObjects array into a single object in the format that you want.
const flattenedObjects = [
{name: 'Bill', city: 1},
{name: 'Guillermo', city: 1},
{name: 'Wilhem', city: 1},
{name: 'William', city: 1},
{name: 'Nick', city: 2},
{name: 'Nicolas', city: 2},
{name: 'Nicholas', city: 2},
{name: 'Rick', city: 3},
];
// the keys are the city number rather than city name
const cities = {
1: 'boston',
2: 'miami',
3: 'london',
};
const obj = flattenedObjects.reduce((o, flattenedObject) => {
const cityName = cities[flattenedObject.city];
if (o[cityName] === undefined) {
o[cityName] = [];
}
o[cityName].push(flattenedObject.name);
return o;
}, {});
console.log(obj);
I have an array, like this:
let x = [
{id: 1, name: 'A', age: 34.. lots of other properties},
{id: 2, name: 'B', age: 17.. },
{id: 3, name: 'C', age: 54.. }
]
How can I get this output from it:
let output = [
{id: 1, name: 'A'},
{id: 2, name: 'B'},
{id: 3, name: 'C'}
]
I mean, I can iterate throut it, and push new objects into a new array. But I was thinking if there's a better way to do it..
More generally, for any set of attributes, the idea is called “pick” and "pluck" in lodash and underscore...
let x = [
{id: 1, name: 'A', age: 34 },
{id: 2, name: 'B', age: 17 },
{id: 3, name: 'C', age: 54 }
]
function pick(object, ...attributes) {
const filtered = Object.entries(object).filter(([k, v]) => attributes.includes(k))
return Object.fromEntries(filtered);
}
function pluck(array, ...attributes) {
return array.map(el => pick(el, ...attributes))
}
console.log(pluck(x, 'id', 'name'))
You can use .map
let x = [
{id: 1, name: 'A', age: 34.,},
{id: 2, name: 'B', age: 17., },
{id: 3, name: 'C', age: 54., }
];
console.log(x.map(({id, name}) => ({id, name})));
I have an object where the values are arrays and they've further objects inside them like this:
let primaryStandard = {
section1: [{name: 'andy', id: 1}, {name: 'charles', id: 2},...],
section2: [{name: 'megan', id: 55}, {name: 'derek', id: 56},...],
section3: [{name: 'robert', id: 95}, {name: 'nathan', id: 96},...],
}
Basically, I want to iterate this whole object for a particular id value and then get the name and section in an object.
Example:
For id = 95 the result should be {section: section3, name: 'robert`}
What I've tried so far:
let primaryStandard = {
section1: [{name: 'andy', id: 1}, {name: 'charles', id: 2}],
section2: [{name: 'megan', id: 55}, {name: 'derek', id: 56}],
section3: [{name: 'robert', id: 95}, {name: 'nathan', id: 96}],
}
for (let key of Object.keys(primaryStandard)) {
console.log((primaryStandard[key])) // logs the values(array)
primaryStandard[key].map(student => console.log(student)) // .map() is not defined error
}
You could do this using find method on Object.keys to get section and name.
let data = {section1: [{name: 'andy', id: 1}, {name: 'charles', id: 2}],section2: [{name: 'megan', id: 55}, {name: 'derek', id: 56}],section3: [{name: 'robert', id: 95}, {name: 'nathan', id: 96}],}
let name;
let section = Object.keys(data).find(key => {
const match = data[key].find(({id}) => id == 95);
if(match) return name = match.name
})
console.log({name, section})
I want to use an array method with arrow function. For an example:
const inventory = [
{name: 'apples', quantity: 2, type: 'a'},
{name: 'bananas', quantity: 0, type: 'a'},
{name: 'cherries', quantity: 5, type: 'a'}
{name: 'mangos', quantity: 5, type: 'a'}
];
const result = inventory.filter( fruit => fruit.quantity === 5 );
What if i want to return just the object with the name and type properties? Like this:
console.log(result) //[{name: 'mangos', type: 'a'}, {name: 'cherries', type: 'a'}]
You'd create a new object. It looks like you want to do two things, though: Filter to only items with quantity of 5, and return objects without the quantity field. Unelss you have hundreds of thousands of these¹, you'd do that by using filter then map. Here's an example with destructuring:
const inventory = [
{name: 'apples', quantity: 2, type: 'a'},
{name: 'bananas', quantity: 0, type: 'a'},
{name: 'cherries', quantity: 5, type: 'a'},
{name: 'mangos', quantity: 5, type: 'a'}
];
const result = inventory
.filter(fruit => fruit.quantity === 5)
.map(({name, type}) => ({name, type}));
console.log(result);
¹ If you do have hundreds of thousands of these or more, you might consider just making one pass with forEach.
inventory.filter(fruit => fruit.quantity === 5).map(fruit => ({ name: fruit.name, type: fruit.type }));
map creates a new array using the values you give it, but doesn't change the original, filter creates an array using only the values the function returned a truthy value for.
You can remove the type property by destructuring:
const inventory = [
{name: 'apples', quantity: 2, type: 'a'},
{name: 'bananas', quantity: 0, type: 'a'},
{name: 'cherries', quantity: 5, type: 'a'},
{name: 'mangos', quantity: 5, type: 'a'}
];
const res = inventory.map(({type: x, ...rest}) => rest);
console.log(res);
Or you can just make your array.map callback returning object having only name and quantity field:
const inventory = [
{name: 'apples', quantity: 2, type: 'a'},
{name: 'bananas', quantity: 0, type: 'a'},
{name: 'cherries', quantity: 5, type: 'a'},
{name: 'mangos', quantity: 5, type: 'a'}
];
const res = inventory.map(({name, quantity}) => ({name, quantity}));
console.log(res);
Try using lodash
const inventory = [
{name: 'apples', quantity: 2, type: 'a'},
{name: 'bananas', quantity: 0, type: 'a'},
{name: 'cherries', quantity: 5, type: 'a'}
{name: 'mangos', quantity: 5, type: 'a'}
];
const result = ._map( inventory, (item)=> {
return {
name: item.name,
quantity: item.quantity}
} );
This question already has answers here:
Build tree array from flat array in javascript
(34 answers)
Closed 4 years ago.
My normal array object like this :
var b = [
{id: 1, name: 'England',parent_id: null},
{id: 2, name: 'Spain',parent_id: null},
{id: 3, name: 'Chelsea',parent_id: 1},
{id: 4, name: 'Manchester United',parent_id: 1},
{id: 5, name: 'Real Madrid',parent_id: 2},
{id: 6, name: 'Barcelona',parent_id: 2},
{id: 7, name: 'Hazard',parent_id: 3},
{id: 8, name: 'Morata',parent_id: 3},
{id: 9, name: 'Pogba',parent_id: 4},
{id: 10, name: 'Lukaku',parent_id: 4},
{id: 11, name: 'Ronaldo',parent_id: 5},
{id: 12, name: 'Bale',parent_id: 5},
{id: 13, name: 'Messi',parent_id: 6},
{id: 14, name: 'Suarez',parent_id: 6},
];
I want to convert the object array to be like this :
var b = [
{
name: 'England',
children: [
{
name: 'Chelsea',
children: [
{name: 'Hazard'},
{name: 'Morata'}
]
},
{
name: 'Manchester United',
children: [
{name: 'Pogba'},
{name: 'Lukaku'}
]
}
]
},
{
name: 'Spain',
children: [
{
name: 'Real Madrid',
children: [
{name: 'Ronaldo'},
{name: 'Bale'}
]
},
{
name: 'Barcelona',
children: [
{name: 'Messi'},
{name: 'Suarez'}
]
},
]
}
];
It seems it will be separated using key parent_id
But i'm still confused to implement it
How can I convert the array object like that?
Please help me guys
.filter() the b so it contains only items with parent_id: null
.map() remaining items, assigning children to them
.map() children for each of the root level parents to return them without parent_id field (optional, not in the example)
var b = [
{id: 1, name: 'England',parent_id: null},
{id: 2, name: 'Spain',parent_id: null},
{id: 3, name: 'Chelsea',parent_id: 1},
{id: 4, name: 'Manchester United',parent_id: 1},
{id: 5, name: 'Real Madrid',parent_id: 2},
{id: 6, name: 'Barcelona',parent_id: 2},
{id: 7, name: 'Hazard',parent_id: 3},
{id: 8, name: 'Morata',parent_id: 3},
{id: 9, name: 'Pogba',parent_id: 4},
{id: 10, name: 'Lukaku',parent_id: 4},
{id: 11, name: 'Ronaldo',parent_id: 5},
{id: 12, name: 'Bale',parent_id: 5},
{id: 13, name: 'Messi',parent_id: 6},
{id: 14, name: 'Suarez',parent_id: 6},
];
const done = b.filter(person => !person.parent_id).map(person => {
return {
id : person.id,
name : person.name,
children: b.filter(child => child.parent_id == person.id)
}
});
console.log(done);