【问题标题】:Javascript equivalent to LEFT OUTER JOIN with NULL in WHERE clauseJavascript 相当于 LEFT OUTER JOIN 在 WHERE 子句中带有 NULL
【发布时间】:2020-03-24 21:08:24
【问题描述】:

我有几个这样的 JS 对象:

var formulas = [
    {formulaID: 1, lastManufactureDate: '2020-03-24'},
    {formulaID: 3, lastManufactureDate: '2020-03-20'},
    {formulaID: 7, lastManufactureDate: '2020-03-16'},
    {formulaID: 9, lastManufactureDate: '2020-03-20'}
];

var allFormulas = [
    {formulaID: 1, formulaName: 'Chocolate Milk 2%'},
    {formulaID: 2, formulaName: 'Chocolate Milk 1%'},
    {formulaID: 3, formulaName: 'Vanilla Creamer'},
    {formulaID: 4, formulaName: 'Hazelnut Creamer'},
    {formulaID: 5, formulaName: 'Plain Creamer'},
    {formulaID: 6, formulaName: 'White Milk 2%'}
];

我需要找到一种方法来识别formulas 数组中的所有对象,这些对象具有allFormulas 数组中不存在的formulaID。基本上,相当于使用 WHERE 子句执行 LEFT OUTER JOIN 以在右侧查找 NULL。在此处的示例数据中,预期输出为
[{formulaID: 7, lastManufactureDate: '2020-03-16'}, {formulaID: 9, lastManufactureDate: '2020-03-20'}]

在应用程序中,formulas 数组中的对象数量约为 135,allFormulas 数组中的对象数量约为 1,100。

我们的目标是在没有第三方库的情况下高效地执行此操作。我发现了一个类似的问题here,但它没有解决识别一个数组中不在另一个数组中的对象。不幸的是,我真的不知道从哪里开始解决这个问题。

【问题讨论】:

标签: javascript


【解决方案1】:

使用allFormulas ids 构建一个集合,然后过滤第一个数组。

var ids = new Set(allFormulas.map(f => f.formulaID));
var result = formulas.filter(f => !ids.has(f.formulaID));

这是O(N+M)的复杂度(每个数组的一次迭代,查找一个集合应该是O(1))。 基于嵌套循环(使用线性搜索,例如find)的解决方案是O(N*M),这对于大型数组来说更糟糕。

【讨论】:

    【解决方案2】:

    var formulas = [{
        formulaID: 1,
        lastManufactureDate: '2020-03-24'
      },
      {
        formulaID: 3,
        lastManufactureDate: '2020-03-20'
      },
      {
        formulaID: 7,
        lastManufactureDate: '2020-03-16'
      },
      {
        formulaID: 9,
        lastManufactureDate: '2020-03-20'
      }
    ];
    
    var allFormulas = [{
        formulaID: 1,
        formulaName: 'Chocolate Milk 2%'
      },
      {
        formulaID: 2,
        formulaName: 'Chocolate Milk 1%'
      },
      {
        formulaID: 3,
        formulaName: 'Vanilla Creamer'
      },
      {
        formulaID: 4,
        formulaName: 'Hazelnut Creamer'
      },
      {
        formulaID: 5,
        formulaName: 'Plain Creamer'
      },
      {
        formulaID: 6,
        formulaName: 'White Milk 2%'
      }
    ];
    
    let preResult = formulas.map((f) => {
      if (!allFormulas.find((x) => x.formulaID == f.formulaID)) {
        return f
      }
    });
    let result = preResult.filter(function(el) {
      return el != null;
    });
    console.log(result);

    当我们试图识别公式数组中存在但不在 allFormulas 中的项目时,我们映射公式并使用 find 方法检查该对象 id 是否存在于 allFormulas 中。在我们使用 map 的过程中,它为匹配的项目返回 undefined(因为我们只返回不匹配的项目)。为了过滤掉 preResults 对象中未定义的内容,我们使用了过滤器。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2011-01-30
      • 1970-01-01
      • 2010-11-26
      • 2018-12-04
      • 1970-01-01
      • 2013-05-22
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      相关资源
      最近更新 更多