4

假设我们有 2 组对象

set1 = [{'id':'1', 'x':'1', 'y':'2'}, {'id':'2', 'x':'2', 'y':'2'}]
set2 = [{'id':'1', 'z':'1'}, {'id':'2', 'z':'2'}]

我们想要:

set3 = set1.join(set2).on('id'); 

>> set3 
[{'id':'1', 'x':'1', 'y':'2', 'z':'1'},{'id':'2', 'x':'2', 'y':'2', 'z':'2'}]

实现此功能的正确工具是什么?可以underscore帮到这里吗?

4

3 回答 3

3

选项1,纯js

我建议您将每个列表转换为 id 集合,例如

{1: {x: 1, y: 1}, 2: {x: 2, y: 2}}

然后对一个(或两个)集合运行 a 并使用这两个集合的属性创建一个新字典 - 后一点取决于您是在寻找内部联接还是外部联接。这应该会导致大致线性的运行时,字典的 javascript 实现非常有效。

选项 2,下划线,对于密集的 id 集,使用 _.zip()

如果id's 相对密集,并且您希望外连接或提前知道 id 集完全相同,另一种选择是将数据填充到三个数组中 - 每个属性一个数组,然后使用下划线zip() 方法。

选项 3,下划线,使用 _.groupBy()

使用自定义比较方法在您拥有的列表上运行 _.groupBy() 的另一种可能性,这也将允许加入多个键。但是,将需要一些简单的后处理,因为直接结果将是形式的字典

{1: [{'id':'1', 'x':'1', 'y':'2'}, {'id':'1', 'z':'1'}],
 2: [{'id':'2', 'x':'2', 'y':'2'}, {'id':'2', 'z':'2'}]}

后一种情况下的内部连接行为可以通过过滤掉结果字典中没有列表中最大项目数的项目(在示例中为 2)来实现。

于 2012-08-18T10:01:20.797 回答
3

选项 4:Alasql

Alasql 可以“SQL 方式”连接两个表。:

var set1 = [{'id':'1', 'x':'1', 'y':'2'}, {'id':'2', 'x':'2', 'y':'2'}];
var set2 = [{'id':'1', 'z':'1'}, {'id':'2', 'z':'2'}];

var res = alasql('SELECT * FROM ? set1 JOIN ? set2 USING id',[set1, set2]);

它准确地提供了您需要的东西:

[{"z":"1","id":"1","x":"1","y":"2"},{"z":"2","id":"2","x":"2","y":"2"}]

在 jsFiddle试试这个例子。

于 2014-12-18T03:37:56.690 回答
1

使用 Ramda 的另一种选择:

const r = require('ramda')
const outerJoin = r.curry(function(relationName, set1, keyName1, set2, keyName2) {
    const processRecord = function(record1) {
        const key1 = record1[keyName1]
        const findIn2 = r.find(r.propEq(keyName2, key1))
        const record2 = findIn2(set2)
        record1[relationName] = record2
        return record1
    }
    return r.map(processRecord, set1)
})

假设

  //set1 is an array of objects
  set1 : [{}]
  //set1 has a property for the key of type T
  set1[keyName1] : T
  //set2 is an array of objects
  set2 : [{}]
  //set2 has a property for the key which is also of type T
  set2[keyName2] : T

输出

 [{
     ...set1 members...
     , relationName: ...set2 members...
  }]

我想更好的输出可能是(应该不难到达这里):

 [{
     , leftObj:...set1 members...
     , rightObj: ...set2 members...
  }]

并添加对内部连接的支持。但是我正在替换一些糟糕的代码并且需要复制对象层次结构。

于 2015-12-15T14:56:29.060 回答