我有一个未排序的数组,其中包含以下ID:
@un_array = ['bar', 'para-3', 'para-2', 'para-7']
是否有一种使用Nokogiri(或普通Javascript)根据下面示例HTML文档中ID的顺序对数组进行排序的智能方法?
require 'rubygems'
require 'nokogiri'
value = Nokogiri::HTML.parse(<<-HTML_END)
"<html>
<head>
</head>
<body>
<p id='para-1'>A</p>
<div id='foo'>
<p id='para-2'>B</p>
<p id='para-3'>C</p>
<div id='bar'>
<p id='para-4'>D</p>
<p id='para-5'>E</p>
<p id='para-6'>F</p>
</div>
<p id='para-7'>G</p>
</div>
<p id='para-8'>H</p>
</body>
</html>"
HTML_END
在这种情况下,生成的排序数组应为:
['para-2', 'para-3', 'bar', 'para-7']
答案 0 :(得分:1)
我不知道Nokogiri是什么,但如果您将HTML代码作为字符串,则可以通过regexp匹配获得订单,例如:
var str = '<html>...</html>'; // the HTML code to check
var ids = ['bar', 'para-3', 'para-2', 'para-7']; // the array with all IDs to check
var reg = new RegExp('(?:id=[\'"])('+ids.join('|')+')(?:[\'"])','g') // the regexp
var result = [], tmp; // array holding the result and a temporary variable
while((tmp = reg.exec(str))!==null)result.push(tmp[1]); // matching the IDs
console.log(result); // ['para-2', 'para-3', 'bar', 'para-7']
使用此代码时,您必须小心包含正则表达式元字符的ID。他们应该先逃脱。
答案 1 :(得分:0)
这是在Nokogiri中实现这一目标的一种方法 - 可能还有其他更有效的方法,因为这最终导致了整个DOM。
require 'set'
#Using a set here to make lookup O(1), because we don't care about the initial order
id_set = ['bar', 'para-3', 'para-2', 'para-7'].to_set
sorted = []
value.root.traverse do |node|
node_id = node['id']
sorted << node_id if node_id && id_set.delete?(node_id)
end
# sorted is now ['para-2', 'para-3', 'bar', 'para-7']
编辑:这是一个获得相同结果的单线程,但我没有做基准测试以确定哪个更快。
ids = ['bar', 'para-3', 'para-2', 'para-7']
value.xpath("//*[@id]").collect {|node| node['id']} & ids
答案 2 :(得分:0)
这是同事和我提出的解决方案:
parent = value.css('body').first
indexes = []
parent.children.each do |child|
indexes << child['id']
end
puts @un_array.sort! { |x,y| indexes.index(x) <=> indexes.index(y) }
首先,我将HTML文档的所有ID都提取到一个数组中,而不是根据我之前创建的ID-Array对@un_array
进行排序。