【问题标题】:Linq JS join syntaxLinq JS 连接语法
【发布时间】:2017-09-22 23:35:58
【问题描述】:

我正在尝试将一组日期和值加入到一组日期中,而不过滤掉额外的日期。 LinqJS 参考here 对我将如何实际使用连接感到非常困惑。 here 的问题也没有多大帮助。

编辑

在此处加入文档:https://svschmidt.github.io/linqjs/Collection.html#Join

看来我需要帮助来弄清楚如何让联接成为 outer 而不是 inner 联接,因此它包含空值/未定义值。

假设我有两个数组:

数组 1:

[
'2017-02-10',
'2017-02-11',
'2017-02-12',
'2017-02-13',
'2017-02-20',
'2017-02-21',
'2017-02-22',
'2017-02-23',
'2017-02-24',
'2017-02-25',
'2017-02-26',
'2017-02-27'
]

数组 2:

[
  { date: '2017-02-10', value:  5 },
  { date: '2017-02-12', value:  8 },
  { date: '2017-02-13', value: 13 },
  { date: '2017-02-21', value: 14 },
  { date: '2017-02-24', value: 11 },
  { date: '2017-02-27', value:  7 }
]

我想加入他们,所以我得到了这个结果(- for undefined):

[
'5',
-,
'8',
'13',
-,
'14',
-,
-,
'11',
-,
-,
'7'
]

我目前的语法:

Enumerable.from(array1).join(array2, '$', '$.date', "outer, inner => inner.value").toArray()

这会产生一个值数组,但结果仍然是内部连接的,它会过滤掉可能是 null/undefined 项的内容。

我该怎么做?对于 LinqJS,join 语法是如何工作的?

【问题讨论】:

  • 您不能同时加入这两个数组,因为它们的内容不同。不过,您可以将它们转换为最终的新数组。
  • 你需要用Linq还是vanilla js也可以?
  • 我想你的意思是这个库:github.com/SvSchmidt/linqjs,我更喜欢 github 的自述文件的样子;)
  • @MaxZoom 你能解释一下为什么会这样吗?我知道你可以用 LinqJS 选择你想加入的键,我只是不知道怎么做。
  • 第一个数组是字符串数组,而第二个数组包含对象。您需要沿第二个数组的结构转换第一个数组。

标签: javascript arrays linq join left-join


【解决方案1】:

你可以使用GroupJoin

根据键的相等性关联两个序列的元素并对结果进行分组。默认相等比较器用于比较键。

对于 LEFT OUTER JOIN 并指定想要的值并使用 DefaultIfEmpty

如果序列为空,则返回指定序列的元素或单例集合中的指定值。

如果为空,则需要替换。

var dates = ['2017-02-10', '2017-02-11', '2017-02-12', '2017-02-13', '2017-02-20', '2017-02-21', '2017-02-22', '2017-02-23', '2017-02-24', '2017-02-25', '2017-02-26', '2017-02-27'],
    values = [{ date: '2017-02-10', value: 5 }, { date: '2017-02-12', value: 8 }, { date: '2017-02-13', value: 13 }, { date: '2017-02-21', value: 14 }, { date: '2017-02-24', value: 11 }, { date: '2017-02-27', value: 7 }],
    result = Enumerable
        .From(dates)
        .GroupJoin(
            values,
           '',
           '$.date',
           't, u => ({ date: t, value: u.Select("$.value").DefaultIfEmpty("-").ToString() })')
        .ToArray();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>

ES6

var dates = ['2017-02-10', '2017-02-11', '2017-02-12', '2017-02-13', '2017-02-20', '2017-02-21', '2017-02-22', '2017-02-23', '2017-02-24', '2017-02-25', '2017-02-26', '2017-02-27'],
    values = [{ date: '2017-02-10', value: 5 }, { date: '2017-02-12', value: 8 }, { date: '2017-02-13', value: 13 }, { date: '2017-02-21', value: 14 }, { date: '2017-02-24', value: 11 }, { date: '2017-02-27', value: 7 }],
    result = Enumerable
        .From(dates)
        .GroupJoin(
            values,
            '',
            '$.date',
            (t, u) => ({
               date: t,
               value: u.Select("$.value").DefaultIfEmpty("-").ToString()
            }))
        .ToArray();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>

【讨论】:

    【解决方案2】:

    我不确定 LinqJS,但普通的 JS 可以做到这一点。

    有几种方法可以解决这个问题。 reduce()map()sort() 函数非常具有 Linq 风格,并且在本机上运行良好。 (还有filter() 和其他一些)。

    const dates = [
    '2017-02-10',
    '2017-02-11',
    '2017-02-12',
    '2017-02-13',
    '2017-02-20',
    '2017-02-21',
    '2017-02-22',
    '2017-02-23',
    '2017-02-24',
    '2017-02-25',
    '2017-02-26',
    '2017-02-27'
    ]
    
    const data = [
      { date: '2017-02-10', value:  5 },
      { date: '2017-02-12', value:  8 },
      { date: '2017-02-13', value: 13 },
      { date: '2017-02-21', value: 14 },
      { date: '2017-02-24', value: 11 },
      { date: '2017-02-27', value:  7 }
    ];
    
    const result = dates
      .map(date => ({ date, value: '-' }))
      .concat(data)
      .filter(({ date, value }) => !(data.find(d => d.date === date) && value === '-'))
      .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
    
    console.log(result);
    
    const justValues = Object.keys(result).map(key => result[key].value);
    
    console.log(justValues);

    【讨论】:

    • 很高兴证明 vanilla JS 是有能力的(或者至少没有人们想象的那么糟糕)
    • 谢谢 Sam,不过,我正在寻找如何使用 LinqJS。我可以很容易地编写 JS 来做到这一点(我已经有这个问题的工作代码),但我更感兴趣的是学习如何使用这个特定的库来执行这个任务。这不是“how do I get this result through any means”的问题,而更像是“how do I get this result with this specific framework”的问题。如果这有意义的话。
    • 是的,我在发布答案后看到了您的评论。
    • 一切都好,我相信这对以后来这里的人会很方便。
    猜你喜欢
    • 2020-08-12
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    相关资源
    最近更新 更多