This question already has answers here:
In JavaScript, how to conditionally add a member to an object?
(29 answers)
Add property to object when it's not null
(3 answers)
Closed 1 year ago.
Let’s consider the next array:
const arr = [
{
name: "bob",
age: 25,
salary: 1000
},
{
name: "bill",
age: 32,
salary: 1500
},
{
name: "jake",
age: 16,
salary: null
},
]
I need to map every object to be the next structure:
firstName: string;
personAge: string;
grossSalary?: number;
so
const mappedArr = arr.map(person => ({
firstName: person.name,
personAge: person.age,
...{grossSalary:
person.salary
? person.salary
: // I'm stuck :'((
}
}))
I need to map person.salary only if it’s not null in the original object. Otherwise, I need to omit it.
I believe I’m pretty close with the spread operator but I guess I need a ternary to return an empty object if the salary is null in the original object. Maybe this approach is wrong... idk anymore...
You can check the salary based on which you can return the object:
const arr = [
{
name: "bob",
age: 25,
salary: 1000
},
{
name: "bill",
age: 32,
salary: 1500
},
{
name: "jake",
age: 16,
salary: null
},
]
const mappedArr = arr.map(person => (
person.salary
? { firstName: person.name, personAge: person.age, grossSalary: person.salary }
: { firstName: person.name, personAge: person.age }
)
);
console.log(mappedArr);
Related
I have one quick question, I want to move all similar professional people into a newly created object (result), I have written the code but all values are not moved.
const data = [
{
Name: 'Smith',
age: 25,
profession: 'Banker'
},
{
Name: 'Alex',
age: 28,
profession: 'IT'
},
{
Name: 'John',
age: 31,
profession: 'Banker'
},
{
Name: 'Harry',
age: 26,
profession: 'Nurse'
},
];
const result = {};
My code is here ...
const data = [ { Name: "Smith", age: 25, profession: "Banker" }, { Name: "Alex", age: 28, profession: "IT" }, { Name: "John", age: 31, profession: "Banker" }, { Name: "Harry", age: 26, profession: "Nurse" } ];
const result = {};
data.forEach(({ Name, age, profession }) => {
result[profession] = { Name, age };
});
console.log(result);
CodePen:
https://codepen.io/Sandy4405/pen/wvmLaJX
Expanding on my comment above, the inside of your forEach should be:
data.forEach(({ Name, age, profession }) => {
if (Array.isArray(result[profession])) {
result[profession].push({ Name, age })
} else {
result[profession] = [{ Name, age }]
}
});
You need to create a nested JSON, which means an array of objects for a similar profession. While iterating, create an array for each profession and use .push() to add the objects. The code would look like below
data.forEach(({Name,age,profession}) => {
result[profession] = result[profession] || [];
result[profession].push({Name,age});
});
Working Version:
const data = [{
Name: "Smith",
age: 25,
profession: "Banker"
},
{
Name: "Alex",
age: 28,
profession: "IT"
},
{
Name: "John",
age: 31,
profession: "Banker"
},
{
Name: "Harry",
age: 26,
profession: "Nurse"
}
];
const result = {};
data.forEach(({
Name,
age,
profession
}) => {
result[profession] = result[profession] || [];
result[profession].push({
Name,
age
});
});
console.log(result);
After the first person with a given profession is encountered, each subsequent person with the same profession will overwrite the previous one. You should instead create an array and push each of the people with the same profession to that array.
First, we'll check if the current profession has been encountered before.
If it hasn't, we'll create an empty array to hold all of the people with this profession.
if (!(profession in result)) {
result[profession] = []
}
Then, since the array is now guaranteed to exist for this profession, we can push to our new array the current person. The next time this profession is encountered, our first check will be skipped and we'll just push the next person onto the array.
result[profession].push({
Name,
age
})
Full example:
const data = [{
Name: "Smith",
age: 25,
profession: "Banker"
}, {
Name: "Alex",
age: 28,
profession: "IT"
}, {
Name: "John",
age: 31,
profession: "Banker"
}, {
Name: "Harry",
age: 26,
profession: "Nurse"
}]
const result = {}
data.forEach(({
Name,
age,
profession
}) => {
if (!(profession in result))
result[profession] = []
result[profession].push({
Name,
age
})
})
console.log(result)
As filipe said in his comment, Your current code is just assigning the values into an object which results in maintaining the single value against keys. To group the same profession values into a respective profession key, You have to do something like this :
const data = [ { Name: "Smith", age: 25, profession: "Banker" }, { Name: "Alex", age: 28, profession: "IT" }, { Name: "John", age: 31, profession: "Banker" }, { Name: "Harry", age: 26, profession: "Nurse" } ];
const result = {};
data.forEach(({ Name, age, profession }) => {
result[profession] ? result[profession].push({ Name, age }) : result[profession] = [{ Name, age }];
});
console.log(result);
This question already has answers here:
Remove property for all objects in array
(18 answers)
Closed 1 year ago.
I have an array of objects with name and age property:
[
{ name: "Matthew", age: 23 },
{ name: "James", age: 20 },
{ name: "Daniel", age: 25 },
{ name: "Joshua", age: 22 }
]
I want to remove age property from all of the objects and print in console like
[
{ name: "Matthew" },
{ name: "James" },
{ name: "Daniel" },
{ name: "Joshua" }
]
Iterate over your array and use delete keyword.
let array = [
{ name: "Matthew", age: 23 },
{ name: "James", age: 20 },
{ name: "Daniel", age: 25 },
{ name: "Joshua", age: 22 }
]
array.forEach(function(v){ delete v.age });
console.log(array);
You can use map function to achieve this.
let output = test.map(({name}) => ({name}));
If you want to filter with multiple object you can add after name like {name, salary}
var test =[
{ name: "Matthew", age: 23 },
{ name: "James", age: 20 },
{ name: "Daniel", age: 25 },
{ name: "Joshua", age: 22 }
];
let output = test.map(({name}) => ({name}));
console.log(JSON.stringify(output, null, 2));
const newData = oldData.map(item=>({name:item.name}))
I have an array of objects, each with various properties. I want to check if one particular property is equal across all of the objects. e.g.
peopleArr = [
{
name: Simon,
age: 22,
hair: brown
},
{
name: John,
age: 22,
hair: black
},
{
name: James,
age: 22,
hair: blond
}
]
I need a function that returns true if age has the same value across all of the objects in the array, and false if not. I've tried some variations using .every, but can't get it to work with object properties specifically (I'm relatively new). Any help appreciated.
You can use array every method and inside the callback check if age in all the object is equal to 22. It will return Boolean value and it will return true if all all the object matches the condition
const peopleArr = [{
name: 'Simon',
age: 22,
hair: 'brown'
},
{
name: 'John',
age: 22,
hair: 'black'
},
{
name: 'James',
age: 23,
hair: 'blond'
}
]
const res = peopleArr.every(item => item.age === 22);
console.log(res)
An alternative to using the .every() method, would be to filter the array and compare the filtered array length to the original array length. Like so
const peopleArr = [
{
name: "Simon",
age: 22,
hair: "brown"
},
{
name: "John",
age: 22,
hair: "black"
},
{
name: "James",
age: 22,
hair: "blond"
}
]
const array_val_same = ( arr, val ) => {
let filtered = arr.filter(el => el.age === val)
return filtered.length === arr.length ? true : false
}
array_val_same(peopleArr, 22)
This is just an alternative, i'd still use .every() though.
I have a navigation function in my React Native app, that outputs to the console all the arguments passed to it in the developer's mode, and sometimes i sent a big store to the arguments and it can not be output. Get the error about the cyclic object reference, because the object is very deep. Therefore I decided to create a function that will check all the fields of the object and depends on it will output the information to the console, for example if the object filed is deeper than 1 level.
const notDeepObj = {
name: 'John',
surname: 'Robert',
age: 28,
family: false,
};
const deepObj = {
name: 'John',
surname: 'Robert',
bankAccount: {
accounts: 2,
cash: true,
credit false,
wasCreated: {
city: 'New-York',
date: '12.02.2020.',
}
}
}
function checkDepthOfObject(obj){}
In the case of not deep object it has to return the object itself like this:
checkDepthOfObject(notDeepObj)
//it will return:
{
name: 'John',
surname: 'Robert',
age: 28,
family: false,
};
And in the case of the deep object it has to return all not deep fields and plus the flag for the deep field of the object:
checkDepthOfObject(notDeepObj)
//it will return:
{
name: 'John',
surname: 'Robert',
bankAccount: '[DEEP_OBJECT]'
};
Can you recommend me please the best way how can I do it.
Use Object.entries and map and check for typeof value.
const notDeepObj = {
name: "John",
surname: "Robert",
age: 28,
family: false
};
const deepObj = {
name: "John",
surname: "Robert",
bankAccount: {
accounts: 2,
cash: true,
credit: false,
wasCreated: {
city: "New-York",
date: "12.02.2020."
}
}
};
function checkDepthOfObject(obj) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [
key,
typeof value === "object" ? "[DEEP_OBJECT]" : value
])
);
}
console.log(checkDepthOfObject(notDeepObj));
console.log(checkDepthOfObject(deepObj));
Say I have 2 arrays users and userCity. I want to map through users array and return updated user object with merged city data from userCity array based on related userId
I get the error:
> *TypeError: Cannot read property 'city' of undefined
> at user.map.u (eval at <anonymous> (:7:47),*
const users = [
{ userId: 1, name: "Jim", age: 25 },
{ userId: 2, name: "Rens", age: 15 },
{ userId: 3, name: "Ed", age: 5 }
];
const userCity = [{ userId: 1, city: "TX" }, { userId: 3, city: "NY", age: 5 }];
const info = users.map(u => {
return {
...u,
city: userCity.find(uc => {
return uc.userId === u.userId;
}).city
};
});
console.log(info);
Note:
I read somewhere that higher-order functions are synchronous therefore I expect the map function to return the values and assign them to info variable.
So I expect the console.log output to be an array with merged user and city info based on userId
[{ userId: 1, name: "Jim", age: 25, city: "TX" },
{ userId: 3, name: "Ed", age: 5, city: "NY" }]
Instead of iterating through users, you will want to iterate through userCity, since you only want to merge data into that array of objects (not the other way round).
With that in mind, when you iterate through userCity, you simply fetch the matching user from the users array by using Array.prototype.find(), using a predicate/callback that enforce a userID match:
const users = [
{ userId: 1, name: "Jim", age: 25 },
{ userId: 2, name: "Rens", age: 15 },
{ userId: 3, name: "Ed", age: 5 }
];
const userCity = [{ userId: 1, city: "TX" }, { userId: 3, city: "NY", age: 5 }];
const info = userCity.map(c => {
const user = users.find(u => u.userId = c.userId);
return {...c, ...user};
});
console.log(info);
You need to guard yourself against city info not being found.
const users = [{
userId: 1,
name: "Jim",
age: 25
},
{
userId: 2,
name: "Rens",
age: 15
},
{
userId: 3,
name: "Ed",
age: 5
}
];
const userCity = [{
userId: 1,
city: "TX"
}, {
userId: 3,
city: "NY",
age: 5
}];
const info = users.map(u => {
const foundObj = userCity.find(uc => uc.userId === u.userId);
return foundObj ? {
...u,
city: foundObj.city
} : u;
});
console.log(info);
If rxjs and observables are an option, to provide some modern-ish stream style, you could go this way:
const users = [
{ userId: 1, name: 'Jim', age: 25 },
{ userId: 2, name: 'Rens', age: 15 },
{ userId: 3, name: 'Ed', age: 5 }
];
const userCity = [
{ userId: 1, city: 'TX' },
{ userId: 3, city: 'NY', age: 5 }
];
const users$ = from ( users );
const user_city$ = from ( userCity );
users$.pipe (
switchMap ( x => user_city$.pipe (
filter ( y => x.userId === y.userId ),
map ( y => ( { ...x, ...y } ) )
) ),
scan ( ( acc, curr ) => acc.concat ( curr ), [] ),
last ()
).subscribe ( x => console.log ( x ) );
This should trace out a single array with two merged objects. This sort of pattern is pretty de rigueur (and very useful) these days.
Note you're iterating through users as the top level, though I don't think it'd matter either way.