2009-05-06 7 views
0

У меня есть несортированный массив, содержащий следующие идентификаторы:Nokogiri: Сортировка Массив идентификаторов в соответствии с порядком в HTML-документе

@un_array = ['bar', 'para-3', 'para-2', 'para-7'] 

Есть ли умный способ использования Nokogiri (или простой Javascript) для сортировки массива по к порядку идентификаторов в приведенном ниже примере HTML-документа?

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

Это раствор Коллега и я придумал:

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 документа в массив, чем я сортирую @un_array в соответствии с идентификаторами-массив I созданный ранее.

1

Я не знаю, что Nokogiri, но если у вас есть HTML-код в виде строки, чем это было бы возможно чтобы получить заказ соответствия регулярных выражений, например:

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

с помощью этого кода вы должны быть осторожны с идентификаторами, содержащими регулярных выражений мета-символы. Сначала их нужно сбежать.

0

Вот один из способов сделать это в Нокигири - там могут быть другие, которые более эффективны, так как это заканчивается тем, что идет по всей 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'] 

EDIT: Вот один вкладыш, который получает те же результаты, но я не сделал бенчмаркинга, чтобы увидеть, что быстрее.

ids = ['bar', 'para-3', 'para-2', 'para-7'] 
value.xpath("//*[@id]").collect {|node| node['id']} & ids 

 Смежные вопросы

  • Нет связанных вопросов^_^