Ramda - 如何使用其他数组和多个属性过滤数组

Ramda - How to filter array with other array and multiple properties

我正在尝试使用 Ramda 用另一个数组过滤一个数组。

这是 ELK 算法的边数组。 sourcestargets 是数组,但在这种情况下,这些数组始终具有单个值。

const edges = [
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#2789a940-15d1-4ff0-b2ef-9f6cde676c18",
        "sources": [
            "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"
        ],
        "targets": [
            "2789a940-15d1-4ff0-b2ef-9f6cde676c18"
        ]
    },
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#7cf88eab-5da4-492b-839c-30916fa98fb9",
        "sources": [
            "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"
        ],
        "targets": [
            "7cf88eab-5da4-492b-839c-30916fa98fb9"
        ]
    },
    {
        "id": "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328#53a6d558-c97b-42df-af69-cf27912dd158",
        "sources": [
            "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328"
        ],
        "targets": [
            "53a6d558-c97b-42df-af69-cf27912dd158"
        ]
    }
]

这是第二个数组的示例,我想用它来过滤第一个数组中的值 - id 对应于 sources 中的值,outgoingNodeId 对应于第一个数组 targets 中的值。

const selectedNodes = [
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada",
        "outgoingNodeId": "2789a940-15d1-4ff0-b2ef-9f6cde676c18",
        "groupId": "27",
        "sectionId": "0e09e7dd-0f71-48a1-a843-36d8e85574b3"
    },
    {
        "id": "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328",
        "outgoingNodeId": "53a6d558-c97b-42df-af69-cf27912dd158",
        "groupId": "27",
        "sectionId": "0e09e7dd-0f71-48a1-a843-36d8e85574b3"
    }
]

在这种情况下,结果应如下所示:

const result = [
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#2789a940-15d1-4ff0-b2ef-9f6cde676c18",
        "sources": [
            "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"
        ],
        "targets": [
            "2789a940-15d1-4ff0-b2ef-9f6cde676c18"
        ]
    },
    {
        "id": "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328#53a6d558-c97b-42df-af69-cf27912dd158",
        "sources": [
            "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328"
        ],
        "targets": [
            "53a6d558-c97b-42df-af69-cf27912dd158"
        ]
    }
] 

我尝试了一些东西,但老实说,我没有什么值得在这里展示的东西。

我最后一次尝试是在:

R.pipe(
  R.groupBy(R.prop('sources'))
)(edges)

然后使用R.filter(R.compose(R.flip(R.contains)(selectedNodesIds), R.prop('id')))

过滤

但我不仅需要过滤 sources,还需要过滤 targets

如有任何帮助,我们将不胜感激。谢谢

编辑: 另一个不同方法的例子:

const edges = [
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#2789a940-15d1-4ff0-b2ef-9f6cde676c18",
        "sources": [
            "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"
        ],
        "targets": [
            "2789a940-15d1-4ff0-b2ef-9f6cde676c18"
        ]
    },
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#7cf88eab-5da4-492b-839c-30916fa98fb9",
        "sources": [
            "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"
        ],
        "targets": [
            "7cf88eab-5da4-492b-839c-30916fa98fb9"
        ]
    },
    {
        "id": "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328#53a6d558-c97b-42df-af69-cf27912dd158",
        "sources": [
            "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328"
        ],
        "targets": [
            "53a6d558-c97b-42df-af69-cf27912dd158"
        ]
    },
    ...multipleObjectsHere
]

selectedNodes 只包含一个对象:

const selectedNodes = [
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada",
        "outgoingNodeId": "2789a940-15d1-4ff0-b2ef-9f6cde676c18",
        "groupId": "27",
        "sectionId": "0e09e7dd-0f71-48a1-a843-36d8e85574b3"
    }
]

结果,我们得到:

const result = [
    {
        "id": "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#2789a940-15d1-4ff0-b2ef-9f6cde676c18",
        "sources": [
            "47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"
        ],
        "targets": [
            "2789a940-15d1-4ff0-b2ef-9f6cde676c18"
        ]
    },
    {
        "id": "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328#53a6d558-c97b-42df-af69-cf27912dd158",
        "sources": [
            "fefd95e0-11d0-44f6-9b48-ec2a0ea1b328"
        ],
        "targets": [
            "53a6d558-c97b-42df-af69-cf27912dd158"
        ]
    },
    ...multipleObjectsHere
] 

总而言之,如果某些内容不在 selectedNodes 中,我们不会将其过滤掉并作为结果保留它

使用 R.innerJoin 使用比较函数在 2 个数组之间创建交集:

const { innerJoin, includes } = R

const fn = innerJoin(({ sources, targets }, { id, outgoingNodeId }) => 
  includes(id, sources) && includes(outgoingNodeId, targets)
)

const edges = [{"id":"47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#2789a940-15d1-4ff0-b2ef-9f6cde676c18","sources":["47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"],"targets":["2789a940-15d1-4ff0-b2ef-9f6cde676c18"]},{"id":"47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#7cf88eab-5da4-492b-839c-30916fa98fb9","sources":["47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"],"targets":["7cf88eab-5da4-492b-839c-30916fa98fb9"]},{"id":"fefd95e0-11d0-44f6-9b48-ec2a0ea1b328#53a6d558-c97b-42df-af69-cf27912dd158","sources":["fefd95e0-11d0-44f6-9b48-ec2a0ea1b328"],"targets":["53a6d558-c97b-42df-af69-cf27912dd158"]}]
const selectedNodes = [{"id":"47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada","outgoingNodeId":"2789a940-15d1-4ff0-b2ef-9f6cde676c18","groupId":"27","sectionId":"0e09e7dd-0f71-48a1-a843-36d8e85574b3"},{"id":"fefd95e0-11d0-44f6-9b48-ec2a0ea1b328","outgoingNodeId":"53a6d558-c97b-42df-af69-cf27912dd158","groupId":"27","sectionId":"0e09e7dd-0f71-48a1-a843-36d8e85574b3"}]

const result = fn(edges, selectedNodes)

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

另一个逻辑应该是看id是否包含在源代码中。如果是也勾选outgoingNodeId。如果没有,return true.

const { innerJoin, includes } = R

const fn = innerJoin(({ sources, targets }, { id, outgoingNodeId }) => 
  !includes(id, sources) || includes(outgoingNodeId, targets)
)

const edges = [{"id":"47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#2789a940-15d1-4ff0-b2ef-9f6cde676c18","sources":["47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"],"targets":["2789a940-15d1-4ff0-b2ef-9f6cde676c18"]},{"id":"47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada#7cf88eab-5da4-492b-839c-30916fa98fb9","sources":["47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada"],"targets":["7cf88eab-5da4-492b-839c-30916fa98fb9"]},{"id":"fefd95e0-11d0-44f6-9b48-ec2a0ea1b328#53a6d558-c97b-42df-af69-cf27912dd158","sources":["fefd95e0-11d0-44f6-9b48-ec2a0ea1b328"],"targets":["53a6d558-c97b-42df-af69-cf27912dd158"]}]
const selectedNodes = [{"id":"47c0ffd2-6a2c-4e7f-9fd9-0e1207225ada","outgoingNodeId":"2789a940-15d1-4ff0-b2ef-9f6cde676c18","groupId":"27","sectionId":"0e09e7dd-0f71-48a1-a843-36d8e85574b3"}]

const result = fn(edges, selectedNodes)

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>