javascript - 将数据分组到单独的列表中

标签 javascript jquery arrays

所以我现在遇到了一些逻辑难题。这是我要解决的问题

问题

我正在读取 PDB 文件,当它遍历该文件时,它会创建文件中所有链的列表。该列表看起来像这样

 chainIdList = [A, E, D, F, G, H];

长度可能会有所不同。

我有另一个序列中每个残基的所有 chainId 的列表,数据是我制作的字典,如下所示

chainResidue = {"chainId" : chainId, "residueNumber" : residueNumber}
chainResidue = { "A", "4"} 

所以我想做的是迭代 chainResidues 列表并检查 chainResidue.chainId 是否在 chainList 中。如果是这样,则创建一个匹配的 chainId 的新列表,然后将所有残基编号附加到该列表中。

这有道理吗?

所以最终它看​​起来像

A = [ 4, 6, 7, 8, ... and so on];
E = [ 9, 10];

到目前为止的代码

for (var i = 0; i < chainResidue.length; ++i) {
    for (var j = 0; j < chainList.length; ++j) {
        if (chainResidue[i].chainId === chainList[j]) {
           //Append value of the chainResidue[i].residueName into chainList[j] make a list of lists?
        }
    }
 }

示例数据

ATOM   3434  CA  LEU Y  17      -3.567   5.653  33.836  1.00 28.21           C  
ATOM   3435  C   LEU Y  17      -3.114   6.290  32.530  1.00 31.33           C  
ATOM   3436  O   LEU Y  17      -2.020   6.873  32.474  1.00 26.01           O  
ATOM   3437  CB  LEU Y  17      -2.620   4.575  34.233  1.00 29.46           C  
ATOM   3438  CG  LEU Y  17      -2.610   4.263  35.705  1.00 33.42           C  
ATOM   3439  CD1 LEU Y  17      -1.430   3.363  35.960  1.00 40.68           C  
ATOM   3440  CD2 LEU Y  17      -2.351   5.483  36.559  1.00 40.12           C  
ATOM   3441  N   ASP Y  18      -3.926   6.263  31.454  1.00 30.62           N  
ATOM   3442  CA  ASP Y  18      -3.487   6.866  30.205  1.00 31.46           C  

我只是拉入“Y”和与其对应的数字,例如 17 和 18。

最佳答案

你可以使用这个 ES6 脚本:

// Sample data
var chainIdList = ['A', 'E', 'D', 'F', 'G', 'H'];
var chainResidue = [
  {"chainId" : "A", "residueNumber" : 24},
  {"chainId" : "E", "residueNumber" : 18},
  {"chainId" : "A", "residueNumber" : 9},
  {"chainId" : "A", "residueNumber" : 15}
];

// Create the empty lists to start with, per letter
var chainIdObj = chainIdList.reduce( (obj, id) => (obj[id] = [], obj), {} );

// Populate those lists with residue numbers
var result = chainResidue.reduce( (res, obj) => (res[obj.chainId] ? res[obj.chainId].push(obj.residueNumber) : 0, res), chainIdObj); 

console.log(result);

代码说明

有两个主要阶段:

  1. 创建一个对象,该对象具有输入数组中每个字母的属性。属性值全部设置为空数组(因为我们还没有处理任何内容)。

chainIdList.reduce 迭代输入数组,并为每个元素调用为其提供的函数。该函数的第一个参数始终是前一个调用的结果。第一次,没有先前的调用,然后它从我们提供给 reduce 的第二个参数的空对象 ({}) 开始。

传递给reduce的函数如下所示:

(obj, id) => (obj[id] = [], obj)

这实际上是 EcmaScript6 于 2015 年引入的较新表示法。在“旧”语法中,它看起来像这样:

function (obj, id) { return obj[id] = [], obj; }

函数体使用逗号运算符,并与return一起使用,它实际上相当于以下代码:

 obj[id] = [];
 return obj;

因此,综合起来,obj 的值以 {} 开头,然后在每次迭代中为其定义一个属性。第一次迭代后是

 { 'A': [] }

...并返回到reduce内部,以便在下一次迭代中作为参数传递,等等。上一次迭代中返回的对象将作为返回值返回整个 reduce 调用。

现在我们的 chainIdObj 等于:

{
  "A": [],
  "E": [],
  "D": [],
  "F": [],
  "G": [],
  "H": []
}
  • 第二阶段用于填充上述结构中的数组。再次强调,迭代是一个reduce;这次是chainResidue。对chainResidue中的每个对象执行的函数是:

    (res, obj) => (res[obj.chainId] ? res[obj.chainId].push(obj.residueNumber) : 0, res)
    
  • 第一个参数 (res) 的第一个值这次不是使用 {} 进行初始化,而是使用上一阶段的结果进行初始化:chainIdObj。上面的函数检查我们正在查看的对象的 chainId 属性值是否与 res 中的条目(即 chainIdObj)中的条目匹配。如果是这样(),则相应的residueNumber将被推送到我们刚刚检查的数组中。在另一种情况下(:)什么都不会发生。但由于三元运算符需要第三个表达式,因此我们只需输入 0:无论如何,表达式的值都会被忽略,因此这只是一个语法填充符。

    最后,再次使用逗号运算符来确保将 res 对象返回到 reduce 内部,以便我们在下一次迭代中再次获取它。最终结果是最后一次迭代的结果,由reduce返回。它被分配给结果

    这就是控制台中输出的内容。

    功能代码

    有些人喜欢尽可能避免变量赋值,并限制将它们用作函数参数。有了上面的元素,你就可以编写这样的代码:

    console.log( chainResidue.reduce( 
       (res, obj) => (res[obj.chainId] ? res[obj.chainId].push(obj.residueNumber) : 0, res), 
                     chainIdList.reduce( (obj, id) => (obj[id] = [], obj), {} ))); 
    

    关于javascript - 将数据分组到单独的列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38593915/

    相关文章:

    python - 将二维动态指针数组作为参数传递给 cython 中的函数

    javascript - Typeahead.js 远程调用限制

    javascript - 如何逐渐加快比赛加时赛的速度

    javascript - fitBounds 调用后增加 map 缩放不起作用

    javascript - jquery加载本 map 片到对话框打开

    Javascript:过滤具有重复日期的数组

    javascript - 图像压缩/调整大小非常慢

    javascript - hash (#) vs end charCode 来自 Firefox 中的按键事件

    Javascript一次更改多个元素边框样式onclick

    java - 代码帮助 - 使用扫描仪初始化字符串数组。显示时数组值全部为空