I have the following variable:
> let location = {0: {1: {name: 'Fred', age: 20}, 5: {name: 'Ema', age: 55}}, 9: {3: {name: 'John', age: 29}}};
And I want to get the items in it:
> console.log(get_items(location));
[{name: 'Fred', age: 20}, {name: 'Ema', age: 55}, {name: 'John', age: 29}]
I've written the following function:
function get_items(location) {
return _.values(location).reduce((items, item)=> items.concat(_.values(item)), []);
}
But I wonder if there is a more elegant solution for this problem.
You could do this with Array#flatMap and Object#values
The Object#values will extract the value(s) of the outer object:
The Array#flatMap would map and flatten the nested objects into a single array of objects after extracting the value by applying the Object#values again for each object:
let data = {0: {1: {name: 'Fred', age: 20}, 5: {name: 'Ema', age: 55}}, 9: {3: {name: 'John', age: 29}}};
const transform = (data) => Object.values(data).flatMap(Object.values);
console.log(transform(data));
Related
How to filter array of objects by property? for example in this array if two or more objects have same properties like name and lastname I want to remove either of them and leave only unique one in an array. example arr:
[ {name: "George", lastname: "GeorgeLast", age: 12},
{name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
result should be either
[ {name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
or
[ {name: "George", lastname: "GeorgeLast", age: 12},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
Apply the technique shown in this answer, which is:
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
...but using findIndex with some criteria rather than just indexOf.
let people = [
{ name: "George", lastname: "GeorgeLast", age: 12 },
{ name: "George", lastname: "GeorgeLast", age: 13 },
{ name: "Bob", lastname: "GeorgeLast", age: 12 }
]
let result = people.filter(
(person, index) => index === people.findIndex(
other => person.name === other.name
&& person.lastname === other.lastname
));
console.log(result);
As for whether it keeps 12-year-old George or 13-year-old George, it is a matter of how findIndex works, which so happens to return the first matching element. So in your example case it will keep 12-year-old George.
The Map object holds key-value pairs and remembers the original insertion order of the keys.
const arr = [
{ name: "George", lastname: "GeorgeLast", age: 12 },
{ name: "George", lastname: "GeorgeLast", age: 13 },
{ name: "Bob", lastname: "GeorgeLast", age: 12 }
];
const newMap = new Map();
arr.forEach((item) => newMap.set(item.name, item));
console.log([...newMap.values()]);
Another solution.
Here you don't need to iterate through the list n*n/2 times (if I count correctly).
On the other hand, this one looks less concise and uses more memory.
Use whichever you prefer.
const arr = [
{name: "George", lastname: "GeorgeLast", age: 12},
{name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}
];
const obj = {}
arr.forEach(v => {
if (!obj[v.name]) {
obj[v.name] = {}
}
if (!obj[v.name][v.lastname]) {
obj[v.name][v.lastname] = v;
}
})
const result = [];
Object.values(obj).forEach(nameObj =>
Object.values(nameObj).forEach(surnObj => result.push(surnObj))
);
console.log(result)
Basically I have this JavaScript array:
const a = [
{name: 'Foo', place: 'US', age: 15},
{name: 'Foo', place: 'UK', age: 21},
{name: 'Bar', place: 'Canada', age: 20},
{name: 'Bar', place: 'China', age: 22}
];
What is the fastest way to make it look like this? (Where the name becomes a single object property in the "a" array). How would I iterate over the array?
const a = [
{
name: 'Foo',
data: [
{
place: 'US', age: 15
},
{
place: 'UK', age: 21
}
]
},
{
name: 'Bar',
data: [
{
place: 'Canada', age: 20
},
{
place: 'China', age: 22
}
]
}
];
Thank you!
You can make use of reduce function to group data based on name property and then take Object.values.
var a = [
{name: 'Foo', place: 'US', age: 15},
{name: 'Foo', place: 'UK', age: 21},
{name: 'Bar', place: 'Canada', age: 20},
{name: 'Bar', place: 'China', age: 22}
];
var result = Object.values(a.reduce((acc, {name, ...rest})=>{
acc[name] = acc[name] || {name, data:[]};
acc[name].data = [...acc[name].data, rest];
return acc;
},{}));
console.log(result);
One way could be to use an ES6 Map. You can use .reduce() to accumulate the objects in a to the Map. Each name can be a key in the map and each value within the map will be an array of objects which have that key as a name. Once you have built the Map, you can use Array.from() to convert the Map to an array, while also providing a mapping function to convert the entries [name, data[]] to objects while the Map to array conversion occurs.
See example below:
const a = [
{name: 'Foo', place: 'US', age: 15},
{name: 'Foo', place: 'UK', age: 21},
{name: 'Bar', place: 'Canada', age: 20},
{name: 'Bar', place: 'China', age: 22}
];
const res = Array.from(a.reduce((m, {name, ...r}) => {
return m.set(name, (m.get(name) || []).concat(r));
}, new Map), ([name, data]) => ({name, data}));
console.log(res);
I have a JavaScript array of objects to sort and arrange it as a new object array preserving the order.
My array of objects. I get them ordered in the way that I want. The index of the objects are 0,1 & 2 in this.
[{0: {name: 'Joel', age:25, id: 2}}, {1: {name: 'Sam', age: 23, id: 4}}, {2: {name: 'Tim', age:27, id: 3}}]
What I want is to make 'id' the index value. And I want it in ascending order of the 'name' (Preserving the above order)
[{2: {name: 'Joel', age:25, id: 2}}, {4: {name: 'Sam', age: 23, id: 4}}, {3: {name: 'Tim', age:27, id: 3}}]
I tried using this function.
for (i in members) {
member[members[i].id] = members[i];
}
But it failed. The output was
[{}, {}, {name: "Joel", age:25, id: 2}, {name: "Tim", age:27, id: 3}, {name: "Sam", age: 23, id: 4}]
I tried using forEach and sort methods too. But all failed.
Is there any way to accomplish this in JavaScript.
You can do it with help of map and sort.
let obj = [{0: {name: 'Joel', age:25, id: 2}}, {1: {name: 'Sam', age: 23, id: 4}}, {2: {name: 'Tim', age:27, id: 3}}]
let op = obj.map((e,index)=>{
return{
[e[index].id] : e[index]
}
}).sort((a,b)=> Object.keys(a) - Object.keys(b))
console.log(op)
I'm using React for my application and I've put my data (objects) into an array. Is there a way to output my data (array of objects) that loads all at once (such as Twitter, Instagram, Facebook)?
Currently I'm using a for loop where it loads one by one from my latest post to the end.
Here's a sample for loop to demonstrate.
var myArray = [
{name: 'Dwayne', age: 28},
{name: 'Rob', age: 32},
{name: 'Marie', age: 22},
{name: 'Sarah', age: 40},
{name: 'Emma', age: 29},
{name: 'James', age: 30}
];
for (var i = myArray.length - 1; i >= 0; i--){
console.log(myArray[i].name, myArray[i].age);
}
Here's an example of using map to generate a <p/> element with name and age inside it.
render(){
const myArray = [
{name: 'Dwayne', age: 28},
{name: 'Rob', age: 32},
{name: 'Marie', age: 22},
{name: 'Sarah', age: 40},
{name: 'Emma', age: 29},
{name: 'James', age: 30}
];
return(
<div>
{myArray.map((item, index) => (
<p key={`${item.name}-${index}`}>
Name:{item.name}, Age:{item.age}
</p>
))}
</div>
)
}
The above code would output
<div>
<p>Name:Dwayne, Age:28</p>
<p>Name:Rob, Age:32</p>
<p>Name:Marie, Age:22</p>
<p>Name:Sarah, Age:40</p>
<p>Name:Emma, Age:29</p>
<p>Name:James, Age:30</p>
</div>
so I've got this Array
var gillFamily = [{name: 'john', age: 20},
{name: 'richard', age: 27},
{name: 'debbie', age: 55},
{name: 'dan', age 25},
{name: 'robin', age 60}]
And using lodash need to find all the people with an age less than 50.
I tried this _.map to see if it would work
_.map(gillFamily, (el) => el.name, (el) => el.age < 50);
and some filter and reduce stuff with functions but cant get it, Thanks.
_.map() transforms an array. It does not remove elements. For example, if your input array is
const family = [
{name: 'john', age: 20},
{name: 'richard', age: 27},
{name: 'debbie', age: 55},
{name: 'dan', age: 25},
{name: 'robin', age: 60}
]
you could use it to transform it into an array containing descriptions of the persons:
_.map(family, p => p.name + " is " + p.age + " years old")
You'll end up with:
[
'john is 20 years old',
'richard is 27 years old',
'debbie is 55 years old',
'dan is 25 years old',
'robin is 60 years old'
]
To get an array containing the persons younger than 50, one way would be to use _.filter():
_.filter(family, p => p.age < 50)
However, this isn't the only way to do it. There are a number of other ways to achieve the same thing using lodash, and ES6 also provides map() and filter() natively.
You need to make use of the filter function. filter function iterates over elements of collection, returning an array of all elements where the condition is met. More information here.
map is used to transform the array from one form to another which doesn't meet your requirement.
var gillFamily = [{name: 'john', age: 20},
{name: 'richard', age: 27},
{name: 'debbie', age: 55},
{name: 'dan', age: 25},
{name: 'robin', age: 60}];
var ageLessThan50 = _.filter(gillFamily, person => person.age < 50);
console.log(ageLessThan50);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>