Şeyma Yaman Şeyma Yaman - 1 month ago 5
Javascript Question

Adding prototype to object in Javascript

I have a list like:

ATOM 1 N LYS A 1 37.995 20.521 9.231 1.00 31.96

ATOM 2 CA LYS A 1 38.067 19.342 10.141 1.00 30.87

ATOM 3 C LYS A 1 36.817 18.477 10.027 1.00 28.29

...

ATOM 10 N GLU A 2 36.835 17.337 10.707 1.00 24.26

ATOM 11 CA GLU A 2 35.709 16.412 10.692 1.00 19.83

ATOM 12 C GLU A 2 35.496 15.870 12.098 1.00 18.02

...

I read this list line by line and than parse it. After parse i expect the result like this:

[ { resName: 'LYS',
resSeqNum: 1,
atoms: { atomName: ' N ', x: 37.995, y: 20.521, z: 9.231 }, { atomName: ' CA ', x: 38.067, y: 19.342, z: 10.141 }, { atomName: ' C ', x: 36.817, y: 18.477, z: 10.027 }, ... },
[ { resName: 'GLU',
resSeqNum: 2,
atoms: { atomName: ' N ', x: 36.835, y: 17.337, z: 10.707 }, { atomName: ' CA ', x: 35.709, y: 16.412, z: 10.692 }, { atomName: ' C ', x: 35.496, y: 15.870, z: 12.098 } } ] ]


I try it several ways but results don't like i want. Here is my code:

var someData = ["ATOM 1 N LYS A 1 37.995 20.521 9.231 1.00 31.96 N",
"ATOM 2 CA LYS A 1 38.067 19.342 10.141 1.00 30.87 C",
"ATOM 3 C LYS A 1 36.817 18.477 10.027 1.00 28.29 C" ] ;
var protein = [];
var parse;

function parser(line){
parse = {
resName: line.substring(17, 20),
resSeqNum: parseInt(line.substring(22, 26)),
atoms: {
atomName: line.substring(12, 16),
x: parseFloat(line.substring(30, 38)),
y: parseFloat(line.substring(38, 46)),
z: parseFloat(line.substring(46, 54))
}
}
return parse;
}
for(var i=0; i<someData.length; i++){
protein.push(parser(someData[i]));
}
console.log(protein);


I give a some data for test my code. This code's results like that:

[ { resName: 'LYS',
resSeqNum: 1,
atoms: { atomName: ' N ', x: 37.995, y: 20.521, z: 9.231 } },
{ resName: 'LYS',
resSeqNum: 1,
atoms: { atomName: ' CA ', x: 38.067, y: 19.342, z: 10.141 } },
{ resName: 'LYS',
resSeqNum: 1,
atoms: { atomName: ' C ', x: 36.817, y: 18.477, z: 10.027 } } ]


Can you give me any advice for that?

Answer

You need to create an array for your atoms. Right now, every line gets its own object. There's no grouping by "res name". Here's how you can do it in two steps:

  • For each atom,
  • Check the res name,
  • If it's one we haven't seen, create a new object with an atom array
  • If we've already seen it, use the previously created object
  • push the new atom to the array

var someData = ["ATOM      1  N   LYS A   1      37.995  20.521   9.231  1.00 31.96           N",
                "ATOM      2  CA  LYS A   1      38.067  19.342  10.141  1.00 30.87           C",
                "ATOM      3  C   LYS A   1      36.817  18.477  10.027  1.00 28.29           C",
                "ATOM     10  N   GLU A   2      36.835  17.337  10.707  1.00 24.26",
                "ATOM     11  CA  GLU A   2      35.709  16.412  10.692  1.00 19.83",
                "ATOM     12  C   GLU A   2      35.496  15.870  12.098  1.00 18.02"] ;    

// Parsing logic
var getRes = line => line.substring(17, 20);
var getResSeqNum = line => parseInt(line.substring(22, 26));
var getAtomName = line => line.substring(12, 16);
var getX = line =>  parseFloat(line.substring(30, 38));
var getY = line => parseFloat(line.substring(38, 46));
var getZ = line => parseFloat(line.substring(46, 54));


var parsedBySeq = someData.reduce(function(result, line) {
    var resKey = getRes(line);
    var resSeq = getResSeqNum(line);
    var newAtom = {
        atomName: getAtomName(line),
        x: getX(line),
        y: getY(line),
        z: getZ(line),
    };
    
    if (!result[resKey]) { // First time we've seen a res with name 'resKey'
        result[resKey] = { 
          resName: resKey, 
          resSeqNum: resSeq, 
          atoms: [newAtom] 
        };
    } else { // Previously encountered atoms had the same name, add this one to it
        result[resKey].atoms.push(newAtom);
    }

    return result;
}, {});


var parsedArr = Object.keys(parsedBySeq).map(k => parsedBySeq[k]);

console.log(parsedArr);
.as-console-wrapper { min-height: 100%; }

Comments