Javascript Nokogiri:根据HTML文档中的顺序对ID数组进行排序

Javascript Nokogiri:根据HTML文档中的顺序对ID数组进行排序,javascript,ruby-on-rails,ruby,dom,nokogiri,Javascript,Ruby On Rails,Ruby,Dom,Nokogiri,我有一个未排序的数组,其中包含以下ID: @un_array = ['bar', 'para-3', 'para-2', 'para-7'] 在下面的示例HTML文档中,是否有一种聪明的方法可以使用(或纯Javascript)根据ID的顺序对数组进行排序 require 'rubygems' require 'nokogiri' value = Nokogiri::HTML.parse(<<-HTML_END) "<html> <head>

我有一个未排序的数组,其中包含以下ID:

@un_array = ['bar', 'para-3', 'para-2', 'para-7']
在下面的示例HTML文档中,是否有一种聪明的方法可以使用(或纯Javascript)根据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

我不知道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']
var str='…';//要检查的HTML代码
变量ID=['bar'、'para-3'、'para-2'、'para-7'];//包含要检查的所有ID的数组
var reg=new RegExp(“(?:id=[\'”)(“+ids.join(“\;”)+”)(?:[\'”),“g”)//RegExp
var result=[],tmp;//包含结果和临时变量的数组
while((tmp=reg.exec(str))!==null)result.push(tmp[1]);//匹配ID
console.log(结果);//[“第2款”、“第3款”、“酒吧”、“第7款”]

使用此代码时,必须小心使用包含regexp元字符的ID。它们应该首先被转义。

在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']

这是我和一位同事提出的解决方案:

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) }
parent=value.css('body')。首先
索引=[]
parent.children.each do| child|
索引
ids = ['bar', 'para-3', 'para-2', 'para-7']
value.xpath("//*[@id]").collect {|node| node['id']} & ids
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) }