Hatena::Grouprubyist

Going My Ruby Way このページをアンテナに追加 RSSフィード

Ruby ロゴ (C) Ruby Association LLC

2012年04月03日(火)

Array#zip

| 19:03 | Array#zip - Going My Ruby Way を含むブックマーク はてなブックマーク - Array#zip - Going My Ruby Way Array#zip - Going My Ruby Way のブックマークコメント

Array#zip のメモです。

普通、こう使います。

[:a,:b,:c].zip([1,2,3])       # => [[:a, 1], [:b, 2], [:c, 3]]

[:a,:b].zip([1,2],["x","y"])  # =>  [[:a, 1, "x"], [:b, 2, "y"]]

zip は引数が必須と思い込んでたんですが、引数がない場合以下のようになりました。

[:a,:b,:c].zip                # => [[:a], [:b], [:c]]

引数に空配列を渡すと以下のようになります。

[:a,:b,:c].zip([])            # => [[:a, nil], [:b, nil], [:c, nil]]

FizzBuzz その2

| 18:49 | FizzBuzz その2 - Going My Ruby Way を含むブックマーク はてなブックマーク - FizzBuzz その2 - Going My Ruby Way FizzBuzz その2 - Going My Ruby Way のブックマークコメント

FizzBuzz について、その2。

新案。この方が素直?

gen = -> s,n { -> count { s if count % n == 0 } }  # 構文は Ruby1.9
fizz = gen['Fizz', 3]
buzz = gen['Buzz', 5]
ans = (1..100).map {|n| "#{fizz[n]}#{buzz[n]}".sub(/^$/) { n } }

オープンクラスででも、できなくはない。

class Numeric
  def fizzbuzz ; 'FizzBuzz' if self % 15 == 0 ; end
  def fizz     ; 'Fizz'     if self %  3 == 0 ; end
  def buzz     ; 'Buzz'     if self %  5 == 0 ; end
end

ans = (1..100).map {|n| n.fizzbuzz || n.fizz || n.buzz || n }

前の日記

何故か、前は一つの式にまとめるのにこだわってたようです。

Nokogiri

| 00:56 |  Nokogiri - Going My Ruby Way を含むブックマーク はてなブックマーク -  Nokogiri - Going My Ruby Way  Nokogiri - Going My Ruby Way のブックマークコメント

スクレイピングツールの Nokogiri を初めて使ってみました。

簡単なメモ。

require 'nokogiri'

doc = open('test.html') {|f| Nokogiri::HTML f } # Nokogiri::HTML::Document の取得

doc.class # => Nokogiri::HTML::Document

ノードの検索には xpathcss などのメソッドが使えます。

軸の指定や id() は使えない(やり方が悪い?)ようですが xpath メソッドは強力です。

nodes = doc.xpath('//ul/li/text()') # XPath の書式でロケーションパスを指定

nodes.class # => Nokogiri::XML::NodeSet

ノードが一つだけ返るロケーションパスを指定しても(ノードが一つだけの)NodeSet が返ります。(ノード(Element など)が返るわけでありません)

nodes = doc.xpath('//ul/li[1]')    # ちなみに、XPath のインデックスは「1」から始まる

nodes.class # => Nokogiri::XML::NodeSet
nodes.count # => 1

NodeSet は Enumerable です。 NodeSet#[] で子要素を取得できます。

Nokogiri::XML::NodeSet.ancestors # => [Nokogiri::XML::NodeSet, Enumerable, ...

nodes[0].class # => Nokogiri::XML::Element (0 番目の子が要素の場合)
nodes[1].class # => Nokogiri::XML::Text    (1 番目の子がテキストの場合)

要素の属性値、子ノード、テキストの取得

elem = nodes[0]

elem[:src]       # src 属性の値が返る。elem.attribute('src').value と同じ
elem.children    # 子ノード(NodeSet)が返る
elem.text        # 自分以下のサブツリーのテキストを結合した文字列が返る

参考

YAML での true とか nil とか 空文字列とか [] の出力

| 00:04 |  YAML での true とか nil とか 空文字列とか [] の出力 - Going My Ruby Way を含むブックマーク はてなブックマーク -  YAML での true とか nil とか 空文字列とか [] の出力 - Going My Ruby Way  YAML での true とか nil とか 空文字列とか [] の出力 - Going My Ruby Way のブックマークコメント

$ irb -r yaml
>> y [true, false, TRUE, FALSE, nil, :symbol, "", [], {}]
--- 
- true
- false
- true
- false
- 
- :symbol
- ""
- []

- {}

上のキーワードと区別できなくなるような文字列はダブルクォートで囲まれて出力される。(nil は区別がつくので囲まれずに普通の文字列として出力される)

>> y ["true", "false", "TRUE", "FALSE", "nil", ":symbol", '""', "[]", "{}"]
--- 
- "true"
- "false"
- "TRUE"
- "FALSE"
- nil
- ":symbol"
- "\"\""
- "[]"
- "{}"

[比較] 普通の文字列、配列、ハッシュの出力。

>> y "hello"
--- hello
>> y [1,2,3]
--- 
- 1
- 2
- 3
>> y ({:a=>1, :b=>2})
--- 
:a: 1
:b: 2