【问题标题】:Finding optimal nodes whose presence satisfies nested JSON logic寻找满足嵌套 JSON 逻辑的最优节点
【发布时间】:2020-03-26 12:39:14
【问题描述】:

以下是 JSON,我用来生成以下 UI:

{
    "Text" : "1. Parent group"
    "Logic" : "all of the following",
    "Id":"1" //some unique id
    "children": [
        {
            "Text' : "1.1 Level Child group"
            "Logic' : "1 or more of the following",
            "Id':"1.1" //some unique id,
            "children" :  [
                {
                    "Text' : "1.1.1 Level Child group"
                    "Logic' : "all of the following",
                    "Id':"1.1.1" //some unique id,
                    "children": [
                        {
                            "Text' : "1.1.1.1 Level Child"
                            "Id':"1.1.1.1" //some unique id,

                        },
                        {
                            "Text' : "1.1.1.2 Level Child"
                            "Id':"1.1.1.2" //some unique id,
                            "Logic" : "one or more of the following",
                            "children" : [
                                      { 
                                      "Text": "1.1.1.2.1 Level Child", 
                                      "Id": "1.1.1.2.1" 
                                      }, 
                                      { 
                                     "Text": "1.1.1.2.2 Level Child", 
                                      "Id": "1.1.1.2.2" 
                                      }, 
                              ]
                        }
                    ]
                },
                {
                    "Text' : "1.1.2 Level Child group"
                    "Id':"1.1.2" //some unique id,
                },
                {
                    "Text' : "1.1.3 Level Child group"
                    "Id':"1.1.3" //some unique id,
                },
                {
                    "Text' : "1.1.4 Level Child group"
                    "Logic' : "one or more of the following",
                    "Id':"1.1.4" //some unique id,
                    "children": [
                        {
                            "Text' : "1.1.4.1 Level Child"
                            "Id':"1.1.4.1" //some unique id,
                        },
                        {
                            "Text' : "1.1.4.2 Level Child"
                            "Id':"1.1.4.2" //some unique id,
                        }
                    ]
                },
                {
                    "Text' : "1.1.5 Level Child group"
                    "Logic' : "all of the following",
                    "Id':"1.1.5" //some unique id,
                    "children": [
                        {
                            "Text' : "1.1.5.1 Level Child"
                            "Id':"1.1.5.1" //some unique id,
                        },
                        {
                            "Text' : "1.1.5.2 Level Child"
                            "Id':"1.1.5.2" //some unique id,
                        }
                    ]
                }

            ]
        },
        {
            "Text" : "1.2 Level Child"
            "Id":"1.2" //some unique id
        }
    ]
}
1. 家长组(以下全部) 1.1级子组(1个或更多) 1.1.1 级别子组(以下所有) 1.1.1.1 Level Child // 可选 1.1.1.2 Level Child // 可选 1.1.2 Level Child // 可选 1.1.3 Level Child // 可选 1.1.4 级别子组(以下一项或多项) 1.1.4.1 Level Child // 可选 1.1.4.2 Level Child // 可选 1.1.5 Level Child组(以下所有) 1.1.5.1 Level Child // 可选 1.1.5.2 Level Child // 可选 1.2 Level Child // 可选

节点工作逻辑:

  1. 用户只能选择没有子节点的节点。

  2. 当且仅当所有嵌套的子节点都被选中时,如果逻辑是“所有以下”,则隐式选择节点

  3. 如果逻辑是“下面的n或更多”如果选择“n”嵌套的孩子选择

  4. ,则隐式选择node

场景:如果用户选择1.1.2(隐式满足1.1)和1.2那么“1.父组”就是“ Met”,因此被选中(使全组相遇);

场景:如果用户选择1.1.1.1,用户必须选择1.1.1.2,这样1.1.1就是“Met " 并选择1.2,将使整个组为“Met”。

实际需要是在“不满足父组”时找到最优id:

如果选择任何节点和最顶层的父组仍然没有“满足”。 然后单击按钮,我需要找到并返回最佳节点 ID 他们的存在会使“父组”成为“Met”。

注意:在找到最佳节点 ID 时,如果选择了任何子组,我们应该重视子组。

例如:

如果用户只选择了1.2,最快的方法是 遇到的“父组”是选择1.1.2。但是如果 1.1.1 有任何孩子 选择,那么我应该优先考虑 1.1.1 节点,结果我 需要返回以下ID:[ 1.1.1.2, 1.1.1, 1.1 ]

不确定我应该使用哪种算法来解决这个问题。

【问题讨论】:

  • 您可以从添加有效数据开始。如何知道一个节点是否被选中?
  • 每次选择一个节点时,我都会在一个数组中维护节点id。
  • 它看起来怎么样?
  • 假设用户选择“1.2 Level Child”节点。我所做的只是存储特定节点的节点“Id”。它看起来像这样:[“1.2”]。如果您想要添加一个名为“selected”的属性:true 或 false 基于被选择或取消选择的节点。我能做到。
  • 如果用户选择了一些东西,你从哪里得到选定的节点?

标签: javascript json algorithm tree


【解决方案1】:

这是一个简短的方法,通过查看约束,这些约束现在位于使用 q: 'some'q: 'every' 提及的数据集中。

function select(node, selected) {

    function iter(node) {
        if (!node.children) return [node.Id];
		
        var temp = node.children.map(iter);

        if (node.q === 'every') return [...temp.flat(), node.Id];

        var filtered = temp.filter(a => a.some(v => selected.includes(v)));
        if (filtered.length) return [...filtered.flat(), node.Id];

        return [...temp.reduce((a, b) => b.length < a.length ? b : a), node.Id];
    }

    return iter(node).filter(v => !selected.includes(v));
}

var data = { q: 'every', Text: "1. Parent group", Logic: "all of the following", Id: "1", children: [{ q: 'some', Text: "1.1 Level Child group", Logic: "1 or more of the following", Id: "1.1", children: [{ q: 'every', Text: "1.1.1 Level Child group", Logic: "all of the following", Id: "1.1.1", children: [{ Text: "1.1.1.1 Level Child", Id: "1.1.1.1" }, { Text: "1.1.1.2 Level Child", Id: "1.1.1.2" }] }, { Text: "1.1.2 Level Child group", Id: "1.1.2" }, { Text: "1.1.3 Level Child group", Id: "1.1.3" }, { q: 'some', Text: "1.1.4 Level Child group", Logic: "one or more of the following", Id: "1.1.4", children: [{ Text: "1.1.4.1 Level Child", Id: "1.1.4.1" }, { Text: "1.1.4.2 Level Child", Id: "1.1.4.2" }] }, { q: 'every', Text: "1.1.5 Level Child group", Logic: "all of the following", Id: "1.1.5", children: [{ Text: "1.1.5.1 Level Child", Id: "1.1.5.1" }, { Text: "1.1.5.2 Level Child", Id: "1.1.5.1" }] }] }, { Text: "1.2 Level Child", Id: "1.2" }] };

console.log(select(data, ["1.2"]));
console.log(select(data, ["1.2", "1.1.1.1"]));
console.log(select(data, ["1.1.1.1"]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 代码工作得几乎完美,期望直接子选择应该给予更多权重的用例。如果 "1.1.1.2" 有孩子(请参阅更新的 JSON),则运行 select(data , ["1.1.2","1.1.1.2.2"]) 应该返回 [1.2,1];因为选择了“1.1.2”,所以已经满足“1.1”。
  • 为了修复它,我在var filtered .. var all = node.q === 'every', is1orMore = node.q === 'some', childMetSoFar = 0 ; if (node.children) { node.children.forEach(function(child){ if (!child.children &amp;&amp; selected.includes(child.Id)) { childMetSoFar++ } }); if (is1orMore == true &amp;&amp; childMetSoFar &gt;= 1) {return [];} } 之后添加了这段代码。但是 select(data , ["1.2","1.1.4.2"]) => [] 但返回 [1.1,1] 失败。
  • 到第一个,为什么节点"1.1"不在结果集中?每个一些个条件节点都应该不包含在结果集中吗?
  • 你在这里指的是哪个场景?
  • 这个select(data , ["1.1.2","1.1.1.2.2"])
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 1970-01-01
  • 2022-11-18
  • 2023-03-29
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
相关资源
最近更新 更多