3
\$\begingroup\$

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: "wagnerpeter@bailey-schroeder.example.com",
  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: "garzajustin@vasquez.example.com",
  secondary_phone_number: "+39349330249",
  shoe_size: "38"
  snapchat: "",
  twitter: "",
  url: "",
  youtube: "",
}

End Result:

Data Set 1:

{
  name: "Dustin Peter",
  primary_email: "wagnerpeter@bailey-schroeder.example.com",
  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: "garzajustin@vasquez.example.com",
  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;
\$\endgroup\$
  • \$\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 Dec 7 '18 at 18:29
  • 1
    \$\begingroup\$ Nop, they are random data generated in our server. \$\endgroup\$ – Vera Perrone Dec 7 '18 at 21:29
3
\$\begingroup\$

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: "wagnerpeter@bailey-schroeder.example.com",
  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: "garzajustin@vasquez.example.com",
  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);

\$\endgroup\$
0
\$\begingroup\$

What do you think about this?

  1. Define a regular expression to extract delivery_address and residential_address.
  2. Define dataSet1 and dataSet2 so you can fill them later.
  3. Store primary values into dataSet1 and delete them from data, since you don’t need them anymore.
  4. Loop through the properties of the data object and store non-empty values into dataSet2. If the property matches the regular expression, store its value in the appropriate address sub-object. Otherwise store it directly to dataSet2.

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];
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.