This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 5 years ago.
I want to produce this
[
{name: "james", age: 10},
{name: "john", age: 12},
{name: "johnny", age: 56}
]
My below code failed, got expected token?
let x = [
{name: "james", age: 10, school: "London"},
{name: "john", age: 12, school: "India"},
{name: "johnny", age: 56, school: "USA"}
]
let y = x.map(obj => {name:obj.name, age:obj.age})
console.log(y)
you are missing the () change like this ({name:obj.name, age:obj.age})
You must wrap the returning object literal into parentheses. Otherwise
curly braces will be considered to denote the function’s body. Next
works:
Reference question
let x = [
{name: "james", age: 10, school: "London"},
{name: "john", age: 12, school: "India"},
{name: "johnny", age: 56, school: "USA"}
]
let y = x.map(obj => ({name:obj.name, age:obj.age}))
console.log(y)
When creating objects with arrow expressions, you'll need to wrap the body in parens, or it'll be parsed as an arrow function:
let y = x.map(obj => ({name: obj.name, age: obj.age}));
Just as a reference, this would also work, and be the same:
let x = [
{name: "james", age: 10, school: "London"},
{name: "john", age: 12, school: "India"},
{name: "johnny", age: 56, school: "USA"}
];
let y = x.map(obj => {
return { name:obj.name, age:obj.age };
});
console.log(y);
Related
Given the following structure:
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
}
How can we add to each character the key/value pair of city: 'Quahog' so the output looks as follows:
const item = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30, city: 'Quahog'}], // city added
[{name: 'Chris', age: 16, city: 'Quahog'}], // city added
[{name: 'Stewie', age: 1, city: 'Quahog'}] // city added
]
}
We tried using:
let city = data.characters.[0][0].city;
costs = _.map(items, (itemArray) => {
items = _.map(itemArray, (item) => {
if(!item.city) {
item.city = city;
}
});
But it's not working as intended and we can't get the desired output. Any idea how to accomplish this?
Not sure about the reason for having these single item arrays but this solution will do the work (I'll recommend you take a look at the process that creates this data format which is a little weird)
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
}
const city = data.characters.find(characters => characters.find(character => character.city))[0].city
const dataWithCities = {
...data,
characters: data.characters.map(characters => characters.map(character => character.city ? character : {...character, city}))
}
console.log(dataWithCities)
Here is another way of doing it with .reduce():
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
};
data.characters.reduce((a,c)=>
(c[0].city=a[0].city,a));
console.log(data);
When using .reduce() without a second argument it will pick up the first array element as the initial value which is then used as a template to copy the .city property to all the other elements. The actual return value of the .reduce() method is discarded but the input array itself (data) is modified in the process and is then shown in the console.log() expression.
try this one
let city = data.characters.[0][0].city;
let newdata = [];
data.characters.map(items, (itemArray) => {
items = _.map(itemArray, (item) => {
if(item.city === undefined) {
newdata.push({...item , city});
} else {
newdata.push({...item});
}
})
costs = {...newdata}
You can do this without lodash
const data = {
"show": "Family Guy",
"characters": [
[{name: 'Peter', age: 40, city: 'Quahog'}],
[{name: 'Louis', age: 30}],
[{name: 'Chris', age: 16}],
[{name: 'Stewie', age: 1}]
]
}
const chars = data.characters.map((x)=>{
return {...x[0] , city : x[0].city ? x[0].city : city}
})
const items = {...data , characters : chars};
const { city } = data.characters.find(([item]) => !!item.city?.length)[0];
const newData = {
...data,
characters: data.characters.map(([char]) => [{ ...char, city }])
};
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)
This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 1 year ago.
I have an array called persons, that contains objects and arrays within. I'm trying to get all the first names in the siblings array to display. I have a for loop that is displaying John and Maria, but when i call the siblings, the only names that display are Jenny and Jose. I tried different things, Is there a way to display all the firstnames within the siblings array?
var persons = [{
firstName:"John",
lastName:"Doe",
age:50,
eyeColor:"blue",
weight: 180,
siblings: [
{firstName:"Jenny",
age:43,
eyecolor:"brown",},
{firstName:"Jim",
age:35,
eyecolor:"green",},
{firstName:"Joe",
age:29,
eyecolor:"black",},
] },
{firstName:"Maria",
lastName:"Lopez",
age:19,
eyeColor:"brown",
weight: 120,
siblings: [
{firstName:"George",
age:25,
eyecolor:"brown",},
{firstName:"Jose",
age:20,
eyecolor:"green",},
]},
];
for(i=0; i<persons.length; i++){
console.log(persons[i].firstName);
console.log(persons[i].siblings[i].firstName);
}
You should use the Array.forEach() method to easily loop through the array items. Then just console.log the firstname.
var persons = [{
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue",
weight: 180,
siblings: [{
firstName: "Jenny",
age: 43,
eyecolor: "brown",
},
{
firstName: "Jim",
age: 35,
eyecolor: "green",
},
{
firstName: "Joe",
age: 29,
eyecolor: "black",
},
]
},
{
firstName: "Maria",
lastName: "Lopez",
age: 19,
eyeColor: "brown",
weight: 120,
siblings: [{
firstName: "George",
age: 25,
eyecolor: "brown",
},
{
firstName: "Jose",
age: 20,
eyecolor: "green",
},
]
},
];
persons.forEach(person => console.log(person.firstName))
I would like to get values from object and save it into array...This is how my object is structured.
0: {name: "John Deo", age: 45, gender: "male"}
1: {name: "Mary Jeo", age: 54, gender: "female"}
2: {name: "Saly Meo", age: 55, gender: "female"}
But I am looking for something like this.
0: ["John Deo", 45, "male"]
1: ["Mary Jeo", 54, "female"]
2: ["Saly Meo", 55, "female"]
This is where I got stuck.
for(let i in data){
_.map(data[i], value =>{
console.log(value)
})
}
You can use the function Array.prototype.map to iterate over your data and run the function Object.values on each object to extract its values as an array.
const data = [
{name: "John Deo", age: 45, gender: "male"},
{name: "Mary Jeo", age: 54, gender: "female"},
{name: "Saly Meo", age: 55, gender: "female"}
];
result = data.map(Object.values);
console.log(result);
Note that iterating over properties of an object this way might return then in an arbitrary order so if you need to ensure the order you should use a custom function to extract the values (this is especially easy using ES6 destructuring):
const data = [
{name: "John Deo", age: 45, gender: "male"},
{name: "Mary Jeo", age: 54, gender: "female"},
{name: "Saly Meo", age: 55, gender: "female"}
];
const extractValues = ({name, age, gender}) => [name, age, gender];
result = data.map(extractValues);
console.log(result);
Try this:
data.map(obj => Object.values(obj))
Another option would be to use the Object.values() method.
var obj = {name: "John Deo", age: 45, gender: "male"};
console.log(Object.values(obj));
I have an array of objects and I would like to get the index of the object in the array when I get a match.
I have the array as follows:
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
.....
];
Currently I am using indexOf which worked initially and now it doesn't work properly. It returns -1.
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = x.indexOf(find); // should return 1.
The whole should match in the array and should return the index of that object. How can I achieve this? Should I be using some() ?
Thank you
You can use .find instead of indexOf as 2 objects are never equal ( as they point to different reference in memory ) which is what you seem to pass as an argument.
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let found = x.find(function(item) {
// you can use the condition here
return item.info.id === 564;
});
console.log(found);
To find the index, you can use .findIndex method instead.
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let foundIndex = x.findIndex(function(item) {
// you can use the condition here
return item.info.id === 564;
});
console.log(foundIndex);
Objects cannot be compared by traditional equality in JavaScript. Instead, use the ES6 findIndex method to compare each object's properties with the desired values. Here is an example:
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = x.findIndex(element => element.info.id === find.info.id); // index === 1
The id value seems to be sufficient to identify an object in your scenario; if you need to compare more properties, you could obviously add additional equality checks (e.g., element.name === find.name) with the && operator.
If we live in the _.lodash world than this works since lodash would go deep on objects:
let data = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, age: 22, gender: "female"}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
];
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = _.findIndex(data, (i) => _.isEqual(i, find))
console.log(index) // 1
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
A more brutish approach which obviously it is not performant
and as pointed out wont work if the order of the props is different.
let data = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
];
var objectJSONs = data.map((i) => JSON.stringify(i))
let myJSON = JSON.stringify({name: "maggie", info: { id: 234, gender: "female", age: 22}});
let index = objectJSONs.indexOf(myJSON)
console.log(index) // 1
You can make use of underscore _.isEqual for Object comparison and some() or any looping mechanism to iterate the array.
let iFoundIndex = -1;
let bFound = x.some((data,index) => {
if(_.isEqual(data,find){
iFoundIndex = index;
return true;
}
return false;
}
//console.log(iFoundIndex);