-2

I have an object, Object1 which is the Datamodel for AngularForms Where all the Form functionality has been built using this Model and changing the model is not feasible at this stage.

An Api is requesting the data in format of Object2, to send the data to API I have to copy all the data in Object1 to Object2.

The two objects are as below: just a sample on how different two objects are

object1 = {
    applicant: {
        name : "Abc",
        title : "Mr.",
        addr1 : "",
        addr2 : "",
        email : "someone@example.com"
    },
    nominee: {
        name : "Def",
        title : "Ms.",
        addr1 : "",
        email : "sometwo@example.com",
        mobile : ""
    }, 
    ...
}

and

object2 = {
    "key1_1": "Abc",
    "key1_2": "Mr.",
    "key1_3": "",
    "key1_4": "",
    "key1_5": "someone@example.com",
    "key2_1": "Def",
    "key2_2": "Ms.",
    "key2_3": "",
    "key2_4": "sometwo@example.com",
    "key2_5": "",
    ...
}

I want to able to convert from 1st Object to 2nd Object.I have written function as below. So, calling the function and passing the Object1 as param return Object2 and vice versa.

function convertToObj2(object1){
    obj2 = {
        key1_1 : object1.applicant.name,
        key1_2 : object1.applicant.title,
        key1_3 : object1.applicant.addr1,
        key1_4 : object1.applicant.addr2,
        key1_5 : object1.applicant.email,
        key2_1 : object1.nominee.name,
        key2_2 : object1.nominee.title,
        key2_3 : object1.nominee.addr1,
        key2_4 : object1.nominee.email,
        key2_5 : object1.nominee.mobile,
        ...
    }

    return obj2;
}

function convertToObj1(object2){
    obj1 = {
        applicant: {
            name : object2.key1_1,
            title : object2.key1_2,
            addr1 : object2.key1_3,
            addr2 : object2.key1_4,
            email : object2.key1_5
        },
        nominee: {
            name : object2.key2_1,
            title : object2.key2_2,
            addr1 : object2.key2_3,
            email : object2.key2_4,
            mobile : object2.key2_5
        }, 
        ...
    }
    return obj1;
}

Is there a better way to map these objects to each other, without manually assigning each value to the key, as it is tedious and each object contains 300+ keys?

Note: names of keys are not as shown in exapmle, they are normal words without undersorce and not in alpha order.

Karthikeyan Vedi
  • 1,360
  • 1
  • 11
  • 17
  • For the first case, assuming that you are not changing the names of the deeper level properties, you can just have a nested iteration over the properties. For the second case you will need to have enumerated all the properties that belong to each first-level key. Or is there a prefix for the keys? Like 'person_name' – Thiago Barcala Dec 27 '17 at 10:41
  • 1
    If the key names are not as shown, what distinguishes those that belong in `obj1.key1` from `obj1.key2` ? – Alnitak Dec 27 '17 at 10:44
  • if the key names are just "different" without any distinguishing characteristic then you simply _cannot_ split the object up without somehow enumerating which keys belong in which object. You could do that with a configuration array and then some code to parse both the array and the objects, but it won't end up much simpler. – Alnitak Dec 27 '17 at 10:52
  • Ultimately I'd have to ask why your data requires this structure. Chances are, you're doing it wrong. – Alnitak Dec 27 '17 at 10:53
  • so in the final object the key names will exactly same right? if keys under key1 and keys under key2 are really different. – Koushik Chatterjee Dec 27 '17 at 10:57
  • @Alnitak Why do I need two data models? yes, as a requirement, The Object1 is a DataModel for Angular Form Where all the Form functionality has been built using this Model changing the model is not feasible at this stage , And Object2 is the requesting Api_Service Model in which i have to send the data to service, So to send data to api I have convert form Object1 to Obejct2. – Karthikeyan Vedi Dec 27 '17 at 11:06

5 Answers5

1
function convertToObj2(object1){
  var tmpObj = {};
  var keys = Object.keys(object1);
  for(keyName of keys){
      tmpObj = Object.assign(tmpObj,object1[keyName]);
   }
return tmpObj;
}

Call This Function to convert object1 to object2.

Obeth Samuel
  • 590
  • 1
  • 6
  • 18
0

Maybe this solves your problem (using jquery):

function convertToObj2(object1) {
  var object2 = {};
  $.each(object1, function(key, obj) {
    $.each(obj, function(key1, val1) {
      object2[key1] = val1;
    });
  });
  return object2;
}

function convertToObj1(object2) {
  var object1 = {};
  $.each(object2, function(key, val) {
    var obj1Key = key.substring(0, key.indexOf('_'));
    var obj = {};
    obj[key] = val;
    if (object1[obj1Key] != null) {
      object1[obj1Key][key] = val;
    } else {
      object1[obj1Key] = obj;
    }
  });
  return object1;
}


var object2 = {
  key1_1: "value 1_1",
  key1_2: "value 1_2",
  key1_3: "value 1_3",
  key1_4: "value 1_4",
  key1_5: "value 1_5",
  key2_1: "value 2_1",
  key2_2: "value 2_2",
  key2_3: "value 2_3",
  key2_4: "value 2_4",
  key2_5: "value 2_5",
};


var object1 = {
  key1: {
    key1_1: "value 1_1",
    key1_2: "value 1_2",
    key1_3: "value 1_3",
    key1_4: "value 1_4",
    key1_5: "value 1_5",
  },
  key2: {
    key2_1: "value 2_1",
    key2_2: "value 2_2",
    key2_3: "value 2_3",
    key2_4: "value 2_4",
    key2_5: "value 2_5",
  }
};

$(function() {
  console.log(convertToObj2(object1));
  console.log(convertToObj1(object2));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
cowboycb
  • 539
  • 5
  • 11
0

The only way I can think of to map key value properties from object1 to object2 without manually writing them out line by line is by using a for in loop or for loop with Object.keys(obj).

You can also look at lodash, jQuery or other frontend utility libraries. They generally have helper functions for handling these sort of tasks.

When converting, you want to add a prefix/suffix to each of the keys so that you can convert back and forth between the two object types and also to identify which object type you are dealing with.

I don't really recommend using a for in loop, but hopefully the example below will give you some ideas on a conceptual level.

function convertToObj2(obj1) {
    var obj2Prefix = "__obj2__",
        result = {};

    var key;
    for (key in obj1) {
        if (obj1.hasOwnProperty(key)) {
            // Add the prefix to new obj2 key
            // for identification purposes 
            result[obj2Prefix + key] = obj1[key];
        }
    }  
    return result;
}

Hope this helps :)

J. Lee
  • 513
  • 4
  • 15
0

Thanks for everyone who spent their valuable time finding a solution.

I have solved this with reference to this answer.

Step 1 : created a relation for each key in both the objects

relationArr = 
    [
        ["applicant.name", "key1_1" ],
        ["applicant.title", "key1_2" ],
        ["applicant.addr1", "key1_3" ],
        ["applicant.addr2", "key1_4" ],
        ["applicant.email", "key1_5" ],
        ["nominee.name", "key2_1" ],
        ["nominee.title", "key2_2" ],
        ["nominee.addr1 ", "key2_3" ],
        ["nominee.email", "key2_4" ],
        ["nominee.mobile", "key2_5" ],
        ...
    ]

Step 2 : create a function to add/read a property by key-name enclosed "quotes"

function add_property(returnObj, key, sourceObj, srcKey) {
    if (key == null || key == "null"){
        return;
    }
    var keys = key.split('.');
    while (keys.length > 1) {
        var k = keys.shift();
        if (!returnObj.hasOwnProperty(k)) {
            returnObj[k] = {};
        }
        returnObj = returnObj[k];
    }
    returnObj[keys[0]] = this.read_property(sourceObj, srcKey);
}

function read_property(sourceObj, key) {
    if (key == null || key == "null"){
        return null;
    }
    var keys = key.split('.');
    while (keys.length > 1) {
        var k = keys.shift();
        sourceObj = sourceObj[k];
    }
    return sourceObj[keys[0]] != undefined ? sourceObj[keys[0]] : "";
}

Step 3 : Create a function that takes a source-object and return the converted Object w.r.t relationArr, here fromIndex and toIndex specifies the direction of conversion

function convertObject(relObj, sourceObj, fromIndex, toIndex){
    var returnObj = {};
    for (var i = 0, len = relObj.length; i < len; i++) {
        this.add_property(returnObj, relObj[i][toIndex], sourceObj, relObj[i][fromIndex] )
    }
    return returnObj;
}

So, in this way if I specify the relation of keys once, I am to convert object types, I have added only two object types in relation, If there are more objects just add key of the other object ["applicant.name", "key1_1", "newkey" ], to the relation and will be able to convert

relationArr = [
  ["applicant.name", "key1_1"],
  ["applicant.title", "key1_2"],
  ["applicant.addr1", "key1_3"],
  ["applicant.addr2", "key1_4"],
  ["applicant.email", "key1_5"],
  ["nominee.name", "key2_1"],
  ["nominee.title", "key2_2"],
  ["nominee.addr1 ", "key2_3"],
  ["nominee.email", "key2_4"],
  ["nominee.mobile", "key2_5"]
]


function add_property(returnObj, key, sourceObj, srcKey) {
  if (key == null || key == "null") {
    return;
  }
  var keys = key.split('.');
  while (keys.length > 1) {
    var k = keys.shift();
    if (!returnObj.hasOwnProperty(k)) {
      returnObj[k] = {};
    }
    returnObj = returnObj[k];
  }
  returnObj[keys[0]] = this.read_property(sourceObj, srcKey);
}

function read_property(sourceObj, key) {
  if (key == null || key == "null") {
    return null;
  }
  var keys = key.split('.');
  while (keys.length > 1) {
    var k = keys.shift();
    sourceObj = sourceObj[k];
  }
  return sourceObj[keys[0]] != undefined ? sourceObj[keys[0]] : "";
}

function convertObject(relObj, sourceObj, fromIndex, toIndex) {
  var returnObj = {};
  for (var i = 0, len = relObj.length; i < len; i++) {
    this.add_property(returnObj, relObj[i][toIndex], sourceObj, relObj[i][fromIndex])
  }
  return returnObj;
}



// Converting from Object1 Type to Object2 Type
object1 = {
  applicant: {
    name: "Abc",
    title: "Mr.",
    addr1: "",
    addr2: "",
    email: "someone@example.com"
  },
  nominee: {
    name: "Def",
    title: "Ms.",
    addr1: "",
    email: "sometwo@example.com",
    mobile: ""
  },
}

convertedObject2 = convertObject(relationArr, object1, 0, 1);
console.log(convertedObject2); // prints generated Object2 from Object1

//Converting Object2 Type to Object1
convertedObject1 = convertObject(relationArr, convertedObject2, 1, 0);
console.log(convertedObject1); // prints generated Object1 Converted from Object2
Karthikeyan Vedi
  • 1,360
  • 1
  • 11
  • 17
-1

You can use array#reduce.

var object1 = { key1: { key1_1: "value 1_1", key1_2: "value 1_2", key1_3: "value 1_3", key1_4: "value 1_4", key1_5: "value 1_5", }, key2: { key2_1: "value 2_1", key2_2: "value 2_2", key2_3: "value 2_3", key2_4: "value 2_4", key2_5: "value 2_5", } },
    object2 = { key1_1: "value 1_1", key1_2: "value 1_2", key1_3: "value 1_3", key1_4: "value 1_4", key1_5: "value 1_5", key2_1: "value 2_1", key2_2: "value 2_2", key2_3: "value 2_3", key2_4: "value 2_4", key2_5: "value 2_5"};

var object1ToObject2 = (o) => {
  return Object.keys(o).reduce((r, k) => Object.assign(r,o[k]),{});
}

var object2ToObject1 = (o) => {
  return Object.keys(o).reduce((r,k) => {
    var key = k.split('_')[0];
    r[key] = r[key] || {};
    r[key][k] = o[k];
    return r;
  },{});
}

console.log(object1ToObject2(object1));
console.log(object2ToObject1(object2));
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51