通过根据 Google 脚本中的相同值对齐值来合并 2 个或更多 JSON 数据集

Merging 2 or more JSON datasets by aligning the values based on the same value in Google Scripts

我有几个基于 JSON 的数据集。这是因为数据集是通过 API 调用引入的。我可以更改它,如果它有意义,但它可能会大大降低预期的功能。

现在,每个数据集可以轻松地包含 10,000 条甚至 100,000 条记录,即 dataset.length = 10,000。

现在,在这些数据集中的每一个中,它们都有一个 id 列,允许我连接它们。我本质上想要select一个主要数据集,然后循环遍历次要数据集,找到第一条记录(甚至所有记录) 其中共享相同的标识符。假设 primary.id = secondary.id

这本质上类似于 INNER JOIN,但是 运行使用 JSON 并使用 Google 脚本

我想匹配辅助数据集中的行,并将它们添加到主要数据集中的相关位置,并只将一个数据集输出到文件。

我写了下面的脚本

function mergeRecords(primary,identifiers,columns) {
 
  const args = Array.prototype.slice.call(arguments);
    args.splice(0,3);

  const argsFlat = args.flat();

  if (args.length<1) {
    throw 'Insufficient Number of datasets, please add at least 1 secondary dataset';
  }

 
  try {

    for (var i in primary) {
      var parent = primary[i];

      var a = 0;
      var child = argsFlat[a]; 
    
      while (parent[identifiers] != child[identifiers] && a<argsFlat.length) {
        a++;
      }
       
      columns.forEach(function(x) {
        parent['Child-'+x]=child[x];
       }
      );

    }

    return primary;
   } catch(err) {
        Logger.log(err);
        Logger.log(primary);
        Logger.log(arguments);
        Logger.log(argsFlat);
        Logger.log(columns);
        Logger.log(identifiers);
        Logger.log(a);
        Logger.log(parent.id+' '+child.id);
  }
}

本质上,primary 是用于比较所有其他数据集的主要数据集。 identifier 是目标二级数据集中应该相同的键的名称。 是我要从辅助集中检索的数据属性。

如您所见,我已经规定在 columns 参数之后需要包含参数,否则会出错。

我正在使用 while method/function(老实说我不确定区别,我还是个新手)因为我发现它是比使用

快很多
for (var a in argsFlat) { 
 var child = argsFlat[a];
 if (parent[identifiers] == child[identifiers]) {
    columns.forEach(function(x) {
        parent['Child-'+x]=child[x];
        }
      );
 else {continue;}

即使如果多个数据集与父数据集具有相同的标识符,使用它也允许附加来自不同数据集的数据。

这是我使用的测试源:

function test() {
   var primary = {
     'records': [{
    'id':1234445,
    'name':'Yiz Segall1',
    'email':'123@123.com'},
    {
      'id':567568,
      'name':'viva1',
      'email':'old@new.com1'
    },
    {
      'id':123442,
      'name':'shompie1',
      'email':'shompie@gmail.com1'
    }]
  }

  var secondary = {
     'records': [{
    'id':1234445,
    'name':'2Yiz Segall',
    'email':'2123@123.com',
    'phone':12435435},
    {
      'id':567568,
      'name':'2viva',
      'email':'2old@new.com',
      'phone':4445555
    },
    {
      'id':123442,
      'name':'2shompie',
      'email':'2shompie@gmail.com',
      'phone':5556666
    }]
  }

  var tertiary = {
     'records': [{
    'id':1234445,
    'name':'3Yiz Segall',
    'email':'3123@123.com',
    'address':'32 wisconsin avenue'
    },
    {
      'id':567568,
      'name':'3viva',
      'email':'o3ld@new.com',
      'address':'14 pine street'
    },
    {
      'id':123442,
      'name':'s3hompie',
      'email':'3shompie@gmail.com',
      'address':'15 ny street'
    }]
  }

  var records = mergeRecords(primary.records,'id',['name','email'],secondary.records,tertiary.records);

  Logger.log(records);

}

我的问题有两个:

  1. 虽然测试中第一条记录返回正确,但其他记录只是拉入第一条数据,那么我该如何解决?
    • 这是我测试得到的回复[{email=123@123.com, Child-name=2Yiz Segall, name=Yiz Segall1, Child-email=2123@123.com, id=1234445.0}, {email=old@new.com1, name=viva1, Child-name=2Yiz Segall, id=567568.0, Child-email=2123@123.com}, {name=shompie1, email=shompie@gmail.com1, Child-name=2Yiz Segall, Child-email=2123@123.com, id=123442.0}]
  2. 如果我想让它附加所有与主行具有相同标识符的数据行,我在命名方面遇到了问题。现在,它使用 parent['Child-'+x]=child[x]; 仅适用于第一个实例。我如何让它成为 child1,然后是 child 2,然后是 child 3,这样它就足够灵活,可以适应我需要包括的许多数据集。
    • 我想过使用数据集名称,但是数据被转换成一个数组然后被展平,所以无法分辨它来自哪里,或者有什么简单的方法可以做到这一点?

请记住,此过程起到了正确准备数据输出到文件的作用,此时,我已经 运行 脚本进行 3-4 API 调用。

欢迎任何帮助,谢谢。

作为猜测。尝试改变这个:

parent['Child-'+x]=child[x];

有了这个:

if (!parent['Child-' + x]) {
    parent['Child-' + x] = child[x];
} else {
    let counter = 1;
    while (parent['Child' + counter + '-' + x]) continue;
    parent['Child' + counter + '-' + x] = child[x];
}