Нокогири рекурсивно получает всех потомков

Проблема

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

Цель

  • Рекурсивно получить всех дочерних элементов данного элемента.

Входы: элемент Нокогири

Выходы: массив элементов Nokogiri ИЛИ общее количество дочерних элементов.

Настраивать

  • Руби 1.9.2
  • Драгоценный камень Нокогири

Что я в итоге придумал (это работает, но не так красиво, как мой выбранный ответ ниже)

getChildCount(elem)
    children = elem.children
    return 0 unless children and children.count > 0
    child_count = children.count
    children.each do |child|
        child_count += getChildCount(child)
    end
    child_count
end

person wmarbut    schedule 09.04.2012    source источник
comment
Покажите пример кода, который вы написали, и проблему, с которой вы столкнулись при попытке заставить его работать.   -  person the Tin Man    schedule 09.04.2012
comment
Вам действительно нужно уточнить, что вы вводите, каков желаемый результат, и что вы пытались закодировать самостоятельно, чтобы сделать это, или какие проблемы у вас возникли.   -  person Phrogz    schedule 09.04.2012
comment
Да, вы с Железным Человеком правы. Надеюсь, это прояснит ситуацию. Спасибо за ваши ответы   -  person wmarbut    schedule 10.04.2012


Ответы (1)


метод обхода возвращает текущий узел и все детей в блок, рекурсивно.

# if you would like it to be returned as an array, rather than each node being yielded to a block, you can do this
result = []
doc.traverse {|node| result << node }
result

# or, 
require 'enumerator'
result = doc.enum_for(:traverse).map
person John Douthat    schedule 09.04.2012
comment
+1 (когда я наберу больше голосов за 2 часа). Раньше я не видел этого метода. Спасибо! - person Phrogz; 10.04.2012
comment
пример enum_for потрясающий! - person Dmitry Shvetsov; 27.09.2017