在 Ruby 中构建独特树的最快/最短方法?

发布于 2024-08-08 01:46:29 字数 1404 浏览 1 评论 0原文

假设树有一组定义的节点,从树中构建唯一的元素树的最快/最短/单行(不可能:p)方法是什么,其中许多元素在某些节点中重复/丢失(我们将使用这个算法来解决这个问题,这样我们就不必手动完成)。

它可以是 XML/JSON(哈希),或者其他。所以像这样:


root {
    nodes {
        nodeA {}
        nodeB {
            subNodeA {}
        }
    }
    nodes {
        nodeA {
            subNodeA {}
        }
        nodeB {
            subNodeX {}
        }
    }
}

...转换成这样:


root {
    nodes {
        nodeA {
            subNodeA {}
        }
        nodeB {
            subNodeA {}
            subNodeX {}
        }
    }
}

与 xml 相同:


<root>
    <nodes>
        <nodeA/>
        <nodeB>
            <subNodeA/>
        </nodeB>
    </nodes>
    <nodes>
        <nodeA>
            <subNodeA/>
        </nodeA>
        <nodeB>
            <subNodeX/>
        </nodeB>
    </nodes>
</root>


<root>
    <nodes>
        <nodeA>
            <subNodeA/>
        </nodeA>
        <nodeB>
            <subNodeA/>
            <subNodeX/>
        </nodeB>
    </nodes>
</root>

xml/json 文件可能相当大(1MB+),因此必须以深度优先的方式迭代每个元素,或者看起来需要一段时间。它也可以像上面的例子一样小。

What is the fastest/shortest/one-liner (not possible :p) way to build a unique tree of elements from a tree where many of the elements are duplicated/missing in some nodes, given the tree has a defined set of nodes (which we'd use this algorithm to figure out so we don't have to manually do it).

It could be XML/JSON(hash), or whatever. So something like this:


root {
    nodes {
        nodeA {}
        nodeB {
            subNodeA {}
        }
    }
    nodes {
        nodeA {
            subNodeA {}
        }
        nodeB {
            subNodeX {}
        }
    }
}

...converted to this:


root {
    nodes {
        nodeA {
            subNodeA {}
        }
        nodeB {
            subNodeA {}
            subNodeX {}
        }
    }
}

Same with xml:


<root>
    <nodes>
        <nodeA/>
        <nodeB>
            <subNodeA/>
        </nodeB>
    </nodes>
    <nodes>
        <nodeA>
            <subNodeA/>
        </nodeA>
        <nodeB>
            <subNodeX/>
        </nodeB>
    </nodes>
</root>


<root>
    <nodes>
        <nodeA>
            <subNodeA/>
        </nodeA>
        <nodeB>
            <subNodeA/>
            <subNodeX/>
        </nodeB>
    </nodes>
</root>

The xml/json files could be decently large (1MB+), so having to iterate over every element depth-first or something seems like it would take a while. It could also be as small as the example above.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱花细雨 2024-08-15 01:46:29

这将为您提供一组独特的路径:

require 'nokogiri'
require 'set'

xml = Nokogirl::XML.parse(your_data)
paths = Set.new
xml.traverse {|node| next if node.text?; paths << node.path.gsub(/\[\d+\]/,"").sub(/\/$/,"")}

这可以让您开始吗?

[回复评论中的问题]

添加属性路径也很容易,但我们至少要多行一些:

xml.traverse do |node|
  next if node.text?
  paths << (npath = node.path.gsub(/\[\d+\]/,"").sub(/\/$/,""))
  paths += node.attributes.map {|k,v| "#{npath}@#{k}"}
end

This'll get you a set of unique paths:

require 'nokogiri'
require 'set'

xml = Nokogirl::XML.parse(your_data)
paths = Set.new
xml.traverse {|node| next if node.text?; paths << node.path.gsub(/\[\d+\]/,"").sub(/\/$/,"")}

Does that get you started?

[response to question in comment]

Adding attibute-paths is also easy, but let's go at least a little bit multi-line:

xml.traverse do |node|
  next if node.text?
  paths << (npath = node.path.gsub(/\[\d+\]/,"").sub(/\/$/,""))
  paths += node.attributes.map {|k,v| "#{npath}@#{k}"}
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文