How to understand this Arrays and loops in Ruby? [closed]

谁说胖子不能爱 提交于 2020-01-07 08:47:11

问题


Regarding the following code:

update:

(thank you DGM and The Tin Man for recomendation on code and apneadiving for explanation.)

#################
# get main page
#################
  rows = doc.xpath('//table[@class="articulos"]/tr[td[5]/p/b]')
  i = 0
  details = rows.each do |row|
    detail = {}  
    [
      [:sku, 'td[3]/text()'],
      [:desc, 'td[4]/text()'],
      [:stock, "td[5]/p[@title]"],
      [:price, 'td[6]/text()']
    ].each do |name, xpath|
        detail[name] = row.at_xpath(xpath).to_s.strip

      end
    i = i + 1
    if detail[:sku] != ""
          price = detail[:price].split

          if price[1] == "D"
              currency = 144
          else
              currency = 168
          end
          stock = detail[:stock].gsub(/[^\d]/, '')
          cost = price[0].gsub(",", "").to_f
  end
  • Is the first i = 0, i = i + 1 neccesary?
  • What syntax is this using? details = rows.each do |row|
  • Why would you want to use detail = {}? What is this doing?
  • I do understand .each do |name,xpath| because it is in the order: name, xpath.
  • I guess detail[name] = row.at_xpath(xpath).to_s.strip is saying that, if I call detail[:sku], it will make that row at that xpath to a string strip.

for what I understand after reading Ruby Poignant Book reading the code I wrote above I can maybe translate to Ruby logic words?. If that is not to insulting for Ruby Experts,haha.

First we have a loop of one method, with an array of arrays, inside another one.

variable = variable.method block |block argument|
  variable = {block}
  [ array of arrays
    [ symbol_1, 'string'],
    [ symbol_2, 'string'],
    [ symbol_3, 'string'],
    [ symbol_4, 'string'],
    [ symbol_5, 'string'],
    [ symbol_6, 'string']
  ].method block |symbol, string|
    variable[symbol] = variable.method(method argument).method.kernel_method
  end block
end block

??? is this correct? now I need to explain that using the method , variable, and arguments actual names in the code, lets see:

The rows variable gets a collect message to collect a row of an array of arrays containing the symbol and xpath and for each block of arrays the row and xpath wil be applied a kernel method strip?


回答1:


The first i = 0, i = i + 1 (why is that neccesary here?)

it's useless, you're right

details = rows.collect do |row| what syntax is this for? a array? or what class is using from nokogiri? does nokogiri has anything to do with this or is it only RUBY handling an object.

it's sheer ruby style, it loops the elements of what should be an Array.

It also recreates an Array stored in details containing every element declared at the end of the loop. Here it's detail

detail = {} you see this. why would you want to use this? is this doing something I am not seing?

It initializes detail to an empty Hash which is then filled in the collect loop.

I do understand .collect do |name,xpath| because of the top is in order in name , xpath detail[name] = row.at_xpath(xpath).to_s.strip I guess this is saying that if I call detail[:sku] it will make that row at that xpath to a string strip?

Correct.

what does .map do? is there a syntax tutorial in nokogiri page for this?

map loops all the elements of what should be a Hash. It creates an Array containing links. Duplicates of links are removed from this Array thanks to uniq!

Notice the bang at then end of this function, it means it changes the object.

and why did he had to repeat all data in the #walk trough paginator instead of just using idk some variable?

Don't understand this question.

detail << detail I know this is called a push? so why do anyone want to push some same name haha...

It's a push but it's details << detail so logic is safe.

To conclude, it's not beautiful code but it seems functional :)




回答2:


One thing to note, I did this in my own code recently:

      detail = {}
      [
              [:sku, 'td[3]/text()'],
              [:desc, 'td[4]/text()'],
              [:qty, 'td[5]/text()'],
              [:qty2, 'td[5]/p/b/text()'],
              [:title, 'td[5]/p/@title'],
              [:price, 'td[6]/text()']
      ].collect do |name, xpath|
              detail[name] = row.at_xpath(xpath).to_s.strip
      end

The result of the collect statement is thrown way, and the side effect of stuffing things into detail is the main concern. The collect could be changed to an each, in this case.

      detail = {}
      [
              [:sku, 'td[3]/text()'],
              [:desc, 'td[4]/text()'],
              [:qty, 'td[5]/text()'],
              [:qty2, 'td[5]/p/b/text()'],
              [:title, 'td[5]/p/@title'],
              [:price, 'td[6]/text()']
      ].each do |name, xpath|
              detail[name] = row.at_xpath(xpath).to_s.strip
      end


来源:https://stackoverflow.com/questions/6458255/how-to-understand-this-arrays-and-loops-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!