【问题标题】:Sorting sub-arrays in Neo4jNeo4j中的子数组排序
【发布时间】:2017-04-02 19:51:47
【问题描述】:

我需要从一组数组中删除所有重复项,但我们在这里以特殊方式定义“重复项”:如果两个 4 元素数组以任意顺序共享前两个元素和最后两个元素,则它们是“重复项”以任何顺序。 所以我的想法是将这些数组分成两半,对这些 2 元素半数组进行排序,然后将它们重新组合在一起以形成 4 元素数组。然后我们会有一些重复的教科书可以删除。

这是一个好方法吗?
我们从一组 6 个 4 元素数组开始,其中没有一个与另一个完全相同。

[6, 4, 3, 2]
[4, 6, 2, 3]
[3, 4, 2, 6]
[4, 3, 6, 2]
[3, 6, 2, 4]
[6, 3, 4, 2]

在中间分割每个数组

[[6, 4], [3, 2]] 
[[4, 6], [2, 3]]
[[3, 4], [2, 6]]
[[4, 3], [6, 2]]
[[3, 6], [2, 4]]
[[6, 3], [4, 2]]

这是 Neo4j 中最难的部分! 仅对两个内部数组中的每一个进行排序。

[[4, 6], [2, 3]]
[[4, 6], [2, 3]]
[[3, 4], [2, 6]]
[[3, 4], [2, 6]]
[[3, 6], [2, 4]]
[[3, 6], [2, 4]]

将它们重新组合在一起。

[4, 6, 2, 3]
[4, 6, 2, 3]
[3, 4, 2, 6]
[3, 4, 2, 6]
[3, 6, 2, 4]
[3, 6, 2, 4]

使用 DISTINCT 进行重复数据删除。

[4, 6, 2, 3]
[3, 4, 2, 6]
[3, 6, 2, 4]

【问题讨论】:

    标签: sorting neo4j sub-array


    【解决方案1】:

    这个非常简单的查询(使用您的示例数据)实现了您的方法,这似乎是合理的:

    WITH [
      [6, 4, 3, 2],
      [4, 6, 2, 3],
      [3, 4, 2, 6],
      [4, 3, 6, 2],
      [3, 6, 2, 4],
      [6, 3, 4, 2]
    ] AS data
    UNWIND data AS d
    RETURN DISTINCT
      CASE WHEN d[0] > d[1] THEN [d[1], d[0]] ELSE d[0..2] END +
      CASE WHEN d[2] > d[3] THEN [d[3], d[2]] ELSE d[2..] END AS res;
    

    结果是:

    +-----------+
    | res       |
    +-----------+
    | [4,6,2,3] |
    | [3,4,2,6] |
    | [3,6,2,4] |
    +-----------+
    

    处理任意(偶数)大小的数组:

    以下查询将接受偶数大小的子集合的集合作为输入(不必是 4 个)。它将返回一个不同的、内部正确“排序”的集合。

    例如(注意子集合的大小不必相同):

    WITH [
      [6, 4, 3, 2, 3, 2],
      [3, 4, 2, 6, 7, 8],
      [4, 3, 6, 2, 8, 7],
      [3, 6, 2, 4],
      [6, 3, 4, 2],
      [4, 6, 2, 3, 2, 3]
    ] AS data
    WITH EXTRACT(d IN data |
      REDUCE(s = [], i IN RANGE(0, SIZE(d)-1, 2) | s + CASE WHEN d[i] > d[i+1] THEN [d[i+1], d[i]] ELSE d[i..i+2] END)) AS sorted
    UNWIND sorted AS res
    RETURN DISTINCT res;
    

    上面的输出是:

    +---------------+
    | res           |
    +---------------+
    | [4,6,2,3,2,3] |
    | [3,4,2,6,7,8] |
    | [3,6,2,4]     |
    +---------------+
    

    【讨论】:

    • 这很棘手@cybersam。对于这个特定问题,这是一个非常简洁的解决方案。除了 CASE 本身之外,您还可以添加两个数组并一步调用 DISTINCT 对它们的结果!好的,您可能已经预料到了这一点,但是如果子数组大于 2,有没有办法在没有 CASE 的情况下做到这一点,例如 UNWIND ?在这里帮我讲礼仪;我应该在 StackOveflow 上单独提出一个问题吗?
    • 我想这是需要一个新问题的风口浪尖,但我决定用我的解决方案更新我的答案。
    • 感谢@cybersam。我将不得不玩这个,看看你是如何管理滑动窗口一次向前迈出两个元素的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 2021-11-20
    • 2021-10-02
    • 2012-07-28
    • 2011-12-21
    • 2017-10-15
    • 2012-08-16
    相关资源
    最近更新 更多