I am quite bad at data manipulation and after a lot of time I was finally able to get it working how I wanted. The thing is I don't like all the delete operations, I think the code can be a lot cleaner and the runtime seems somewhat slow on a lot of data. Code readability is very important here but it needs to be small, contained and fast. ES6+ i welcome and of course so are tips and general information.
Input Data:
{
agency: "",
agent: "",
agent_email: "",
agent_phone: "",
date_of_birth: "2007-05-30",
delivery_address: "address - 1",
delivery_city: "city - 1",
delivery_country: "PE",
delivery_state: "state - 1",
delivery_zipcode: "zip_code - 1",
facebook: "",
instagram: "",
name: "Dustin Peter",
primary_email: "[email protected]",
primary_phone_number: "+31622064234",
residential_address: "address - 0",
residential_city: "city - 0",
residential_country: "LC",
residential_state: "state - 0",
residential_zipcode: "zip_code - 0",
secondary_email: "[email protected]",
secondary_phone_number: "+39349330249",
shoe_size: "38"
snapchat: "",
twitter: "",
url: "",
youtube: "",
}
End Result:
Data Set 1:
{
name: "Dustin Peter",
primary_email: "[email protected]",
primary_phone_number: "+31622064234",
}
Data Set 2:
{
date_of_birth: "2007-05-30",
delivery_address: {
address: "address - 1",
city: "city - 1",
country: "PE",
state: "state - 1",
zip_code: "zip_code - 1",
}
residential_address: {
address: "address - 0",
city: "city - 0",
country: "LC",
state: "state - 0",
zip_code: "zip_code - 0",
}
secondary_email: "[email protected]",
secondary_phone_number: "+39349330249",
shoe_size: "38",
}
My Working Code:
const dataSet1 = {
name: data.name,
primary_email: data.primary_email,
primary_phone_number: data.primary_phone_number,
};
const dataSet2 = {};
Object.keys(data).forEach((prop) => {
if (data[prop]) { dataSet2[prop] = data[prop]; }
});
dataSet2.residential_address = {
address: dataSet2.residential_address,
city: dataSet2.residential_city,
country: dataSet2.residential_country,
state: dataSet2.residential_state,
zip_code: dataSet2.residential_zipcode,
};
dataSet2.delivery_address = {
address: dataSet2.delivery_address,
city: dataSet2.delivery_city,
country: dataSet2.delivery_country,
state: dataSet2.delivery_state,
zip_code: dataSet2.delivery_zipcode,
};
delete dataSet2.name;
delete dataSet2.primary_email;
delete dataSet2.primary_phone_number;
delete dataSet2.residential_city;
delete dataSet2.residential_country;
delete dataSet2.residential_state;
delete dataSet2.residential_zip_code;
delete dataSet2.delivery_city;
delete dataSet2.delivery_country;
delete dataSet2.delivery_state;
delete dataSet2.delivery_zip_code;
-
\$\begingroup\$ These are not real names, not, and/or email addresses, are they? In the case they are, please delete the question, anonymize that data and post a new one \$\endgroup\$TomG– TomG2018年12月07日 18:29:48 +00:00Commented Dec 7, 2018 at 18:29
-
1\$\begingroup\$ Nop, they are random data generated in our server. \$\endgroup\$Vera Perrone– Vera Perrone2018年12月07日 21:29:18 +00:00Commented Dec 7, 2018 at 21:29
2 Answers 2
You can use Object.entries()
and .filter()
with RegExp
/date|delivery|residential|secondary|shoe/
and .test()
to filter data from data
, create a function expecting property name and optional separator character to concatenate to property name to replace in returned object spread as values passed to second parameter of Object.assign()
const data = {
agency: "",
agent: "",
agent_email: "",
agent_phone: "",
date_of_birth: "2007-05-30",
delivery_address: "address - 1",
delivery_city: "city - 1",
delivery_country: "PE",
delivery_state: "state - 1",
delivery_zipcode: "zip_code - 1",
facebook: "",
instagram: "",
name: "Dustin Peter",
primary_email: "[email protected]",
primary_phone_number: "+31622064234",
residential_address: "address - 0",
residential_city: "city - 0",
residential_country: "LC",
residential_state: "state - 0",
residential_zipcode: "zip_code - 0",
secondary_email: "[email protected]",
secondary_phone_number: "+39349330249",
shoe_size: "38",
snapchat: "",
twitter: "",
url: "",
youtube: ""
}
let [filters, filtered] = [
['date', 'delivery', 'residential', 'secondary', 'shoe']
, (data, props) => Object.entries(data)
.filter(([key, value]) =>
new RegExp(props.join`|`)
.test(key))
];
const handleProps = (prop, r = '', props = filtered(data, filters)) =>
([...p] = props.filter(([key, value]) =>
new RegExp(prop).test(key)).map(([key, value]) =>
(r ? {[key.replace(new RegExp(prop + r), '')]: value} : value))
, r ? p : p.pop());
const dataSet2 = {
date_of_birth:handleProps('date_of_birth')
, delivery_address: Object.assign({}, ...handleProps('delivery', '_'))
, residential_address: Object.assign({}, ...handleProps('residential', '_'))
, secondary_email: handleProps('secondary_email')
, secondary_phone_number: handleProps('secondary_phone_number')
, shoe_size: handleProps('shoe_size')
};
console.log(dataSet2);
What do you think about this?
- Define a regular expression to extract
delivery_address
andresidential_address
. - Define
dataSet1
anddataSet2
so you can fill them later. - Store primary values into
dataSet1
and delete them fromdata
, since you don’t need them anymore. - Loop through the properties of the
data
object and store non-empty values intodataSet2
. If the property matches the regular expression, store its value in the appropriate address sub-object. Otherwise store it directly todataSet2
.
Ready example:
const addr_rgxp = /^(delivery|residential)_(\w+)$/,
dataSet1 = {},
dataSet2 = {
residential_address: {},
delivery_address: {}
};
for (let prop of ['name', 'primary_email', 'primary_phone_number']) {
dataSet1[prop] = data[prop];
delete data[prop];
}
for (let prop in data) {
if (data[prop]) {
let m = prop.match(addr_rgxp);
if (m) {
let addr_type = m[1] + '_address';
dataSet2[addr_type][m[2]] = data[prop];
} else {
dataSet2[prop] = data[prop];
}
}
}