Merge specific prop of objects into one using es6? - javascript

This is by far the most common question asked in SO, however, all in all, the questions asked refers to merging two whole objects.
In my case, it's quite different.
Suppose I'm given:
const P1 = {
"name" : "Person1",
"profession" : "Student",
"gender" : "Male",
"type" : "Patient",
}
const E1 = {
"age" : "30",
"dob" : "20/12/1970",
"address" : "122 Harrow Street",
"contactNumber" : "07473033312",
}
and I want to merge these two to give me the following:
const Result = {
"name" : "Person1",
"type" : "Patient",
"age" : "30",
"dob" : "20/12/1970",
}
The issue is, I don't want to merge two whole projects. I want to merge specific props without looping.
Currently, we can achieve the merge by using the spread like so:
const data = [...P1, ...E1];.
But this merges both, which I don't want.

const result = (({name, type}, {age, dob}) => ({name, type, age, dob}))(P1, P2);
Just partially destruct P1 and P2 and build up a new object.

Since you're looking for an ES6 way, I'd say using deconstruction is the way to go:
const P1 = {
"name" : "Person1",
"profession" : "Student",
"gender" : "Male",
"type" : "Patient",
}
const E1 = {
"age" : "30",
"dob" : "20/12/1970",
"address" : "122 Harrow Street",
"contactNumber" : "07473033312",
}
const { name, type } = P1;
const { age, dob } = E2;
const Result = { name, type, age, dob };

You could use a complete dynamic approach by using an array for the wanted properties and another for the objects.
Then build a new object out of the found objects.
var p1 = { name: "Person1", profession:"Student", gender:"Male", type:"Patient" },
e1 = { age: "30", dob:"20/12/1970", address:"122 Harrow Street", contactNumber:"07473033312" },
keys = ['name', 'profession', 'age', 'dob'],
objects = [p1, e1],
merged = Object.assign(...keys.map(k => ({ [k]: objects.find(o => k in o)[k] })));
console.log(merged);

I guess your best bet is to unpack and then pack it again:
let {name, type, age, dob} = {...P1, ...E1};
result = {name, type, age, dob}
This is silly, but that's all we've got in ES6.
An alternative would be a function like lodash's _.pick.
If you have an array of source objects, replace {...P1, ...E1} with spreaded Object.assign:
let {name, type, age, dob} = Object.assign({}, ...a);

If you're aware of what properties the merged object should have (in your case name, type, age, dob)
How about defining them like so:
const P1 = {
"name" : "Person1",
"profession" : "Student",
"gender" : "Male",
"type" : "Patient",
}
const E1 = {
"age" : "30",
"dob" : "20/12/1970",
"address" : "122 Harrow Street",
"contactNumber" : "07473033312",
}
const Result = {
"name" : P1.name || E1.name,
"type" : P1.type || E1.type,
"age" : P1.age || E1.age,
"dob" : P1.dob || E1.dob,
}

Related

Set first element of nested array as object keys

I have an array like this:
var values = Array ( );
values [0] = Array ("", "Guest1", "Guest2", "Guest3")
values [1] = Array ("Name", "Hans", "Carl", "Peter")
values [2] = Array ("City", "Berlin", "Tokio", "Washington")
values [3] = Array ("Phone", "123", "234", "345")
I would like to create an object like this:
var data= {
Guest1: { "Name" : "Hans", "City" : "Berlin", "Phone" : "123" },
Guest2: { "Name" : "Carl", "City" : "Tokio", "Phone" : "234" },
Guest3: { "Name" : "Peter", "City" : "Washington", "Phone" : "345" },
};
I got the first key using:
const data = Object.fromEntries(values[0].map(key => [key, 0]));
delete data[""];
However, I am struggling to create the rest of the object.
I would highly recommend finding a way to query your data in a more meaningful shape, but it can be wrangled.
const values = [
["", "Guest1", "Guest2", "Guest3"],
["Name", "Hans", "Carl", "Peter"],
["City", "Berlin", "Tokio", "Washington"],
["Phone", "123", "234", "345"],
]
const [header, ...rows] = values;
const data = {};
for (const [key, ...row] of rows) {
for (const [i, value] of row.entries()) {
(data[header[i + 1]] ??= {})[key] = value;
}
}
console.log(data);
Reference:
for...of
destructuring assignment and ...rest property
nullish coalescing assignment (??=)

delete from json conditionally

I have some JSON that looks like this
var js = '{
"person" : {
"firstname" : "Steve",
"lastname" : "Smith",
"other": [
{
"age" : "32",
"deceased" : false
},
{
"age" : "14",
"deceased" : false
},
{
"age" : "421",
"deceased" : false
}
]
}
}'
I know how I delete all of "other" by doing this
var j = JSON.parse(js)
delete j[person.other]
but what I really want is to delete the "other" node with a condition that is age = 14.
The result JSON I am looking for is
{
"person" : {
"firstname" : "Steve",
"lastname" : "Smith",
"other": [
{
"age" : "32",
"deceased" : false
},
{
"age" : "421",
"deceased" : false
}
]
}
}
I have looked at the delete operator here and it does not provide a conditional.
Sorry if this is too simple a question. I am learning.
Thanks
The best approach to this would be not to alter the json, but create another one instead:
const filtered = { ...json, other: json.other.filter(item => item.age !== "14") }
If you really need to alter the json, you can do the following:
let index = json.other.findIndex(item => item.age === "14")
while (index !== -1) {
json.other.splice(index, 1)
index = json.other.findIndex(item => item.age === "14")
}
You can use a filter on the array doing something like
j[person.other].filter(x => x.age != 14)
Doc on how filter works more in depth here :
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Filter nested objects by property

I am consuming a (badly designed) API which sends the following response:
{
"0" : {
"name" : "John",
"last_name" : "Doe"
},
"1" : {
"name": "Mary",
"last_name": "Ann"
},
[...]
}
As you may have noticed, it is a large JSON object with nested objects. Since it isn't an array, i can't use .filter(). So, how can i filter this large object by a nested object property (e.g. name or last_name)?
You can make it as array using Object.values(type).flat(). Then it will make the object values as single array.
const input1 = {
"0" : {
"name" : "John",
"last_name" : "Doe"
},
"1" : {
"name": "Mary",
"last_name": "Ann"
}
}
function search(input, key) {
return Object.values(input).flat().filter(({ name }) => name === key);
}
console.log(search(input1, "John"));

conditional operator to check same value in an array then filter it

I have an array with user who has a property with the latitude.
How can i do if i want to create a new array with user who has the same latitude ?
my array looks like this :
let arrayToFilter = [
{
"user1" : {
"profile" : {
"name" : "user1",
"age" : "35",
"gender" : "male",
"latitude" : 57.267801888216965,
"longitude" : 16.451598081831214
}
},
"user2" : {
"profile" : {
"name" : "user2",
"age" : "50",
"gender" : "male",
"latitude" : 37.785834,
"longitude" : -122.406417
}
},
"user3" : {
"profile" : {
"name" : "user3",
"age" : "23",
"latitude" : 37.785834,
"longitude" : -122.406417
}
}
}
]
i´ve tried with this, but this does not seem to work...
let arr = arrayToFilter.filter(child => child.latitude === child.latitude)
the problem is your arrayToFilter, it is an array but it has just one item and inside that object you have a key/value user with the information, thus the steps are the following:
loop over the array.
loop over the keys to get the items
finally loop over the users to get the desired info.
notice that because we are doing a map then another map and then filter we are going to get a similar structure as you gave.
Array -> Array -> UserObject.
let user = {
name: 'test',
latitude: 57.267801888216965
}
let arrayToFilter = [{
"user1": {
"profile": {
"name": "user1",
"age": "35",
"gender": "male",
"latitude": 57.267801888216965,
"longitude": 16.451598081831214
}
},
"user2": {
"profile": {
"name": "user2",
"age": "50",
"gender": "male",
"latitude": 37.785834,
"longitude": -122.406417
}
},
"user3": {
"profile": {
"name": "user3",
"age": "23",
"latitude": 37.785834,
"longitude": -122.406417
}
}
}]
//we have to loop over the array because it is an array of objects and the users are actually inside the object of the first item.
let filtered = arrayToFilter.map(items => {
//here we are going to loop to get the keys and then iti will return us an arrar
//with the items inside, then we can apply the filter.
return Object.keys(items).map(k => items[k]).filter(u => u.profile.latitude === user.latitude)
})
console.log(filtered);
The error with your code is that you are comparing the user to itself. Your filter queries whether the user's latitude is equal to its own latitude, this is true for all users and you will get an array back with all users.
It should instead be:
let arr = arrayToFilter.filter(child => child.latitude === latitudeToCompare)
Where latitudeToCompare is the latitude at which you would like to find users with the same latitude.
If what you are looking for is a "group by" option in Javascript, then as per this Stackoverflow post can be implemented with a slight variation as follows:
var groupBy = function(xs, [min, max]) {
return xs.reduce(function(rv, x) {
(min < rv[x['latitude']] < max || []).push(x);
return rv;
}, {});
};
where xs is the array of user objects, and min/max are the minimum and maximum latitude to create a range or bucket of latitudes.
You should be able to use the above to help you figure out a solution for your problem.

Javascript Object output to Array

This is a very very simple question, but for some reason I'm stuck with it.
How can I take an object like:
var billionaire = {
"10" : {
"firstName" : "Steve",
"lastName" : "Jobs",
"company" : "Apple"
},
"11" : {
"firstName" : "Bill",
"lastName" : "Gates",
"company" : "Microsoft"
},
"12" : {
"firstName" : "Warren",
"lastName" : "Buffet",
"company" : "Berkshire Hathaway"
}
};
And Output it into an array like this using pure javascript
var arr = [
"Steve",
"Bill",
"Warren"
];
I do just need the firstName in the array. Thanks for your help and sorry for the easy question.
You can do
var arr = Object.keys(billionaire).map(function(k){ return billionaire[k].firstName });

Categories

Resources