Project

General

Profile

Actions

Feature #1840

closed

Hash に要素追加して self を返すメソッド

Added by ykc@venus.dti.ne.jp (Kimura Yoshihiro) over 15 years ago. Updated over 13 years ago.

Status:
Rejected
Assignee:
-
Target version:
-

Description

=begin
配列から Hash を作るときなどに、よく

a.inject({}) {|h, x| h[x] = ...; h }

みたいにするのはもはやイディオムと言ってよいと思いますが(*1)、
「; h」の部分が少々オマジナイっぽいのが気になっていました。

気になったついでに検索してみたら他にもそのような意見を目にしたので(*2)、
Hash に「要素追加して self を返す」ようなメソッドを追加することを
提案してみます。

いくつか選択肢を考えてみました:

  1. Hash#store が self を返す
    仕様が変わるので互換性の面で問題が出るかもしれません。
    しかも h.store(x, ...) だと字面が多くなるという。
    h.store(*v) のように書けるケースなら短かくなるかもしれません。

  2. Array#insert に合わせて Hash#insert を追加する
    []=, store, insert と似たようなのが複数あるのは、初心者にとって
    単にわかりにくいだけかもしれません。

  3. Hash#<< を追加する
    ML を検索したら、[ruby-list:44686] でまつもとさんが、

    ここからの類推で言うとHashに「<<」演算子を追加したとしても、

    a << b

    は a.store(*b) と期待されてしまうのではないでしょうか。少な
    くとも私は最初そう思いました。

    とおっしゃっているのを見つけました。
    これを使うと、h << [k, v] << ... して h.assoc(k) した結果が Array
    とまったく同じになる、という美しさがあります。
    また、キーと値の配列に対して a.inject({}, &:<<) で済んでしまうのは
    うれしいかもしれません。

  4. Enumerable#each_with_object を使う
    それはそれでありかもしれません。個人的には、each のついでに… と
    いう名前を object が欲しい局面で使うのはなんとなく違和感があります。
    似た名前の each_with_index が self を返すからかもしれません。

  5. その他
    このイディオムを使う局面は、キーの集合を別の集合にマッピングした新
    しい Hash が欲しい、というケースだと思われます。それを
    「キーの集合に {}を inject する」と表現することが、そもそも直感的で
    ないとも考えられます。

    「zip して flatten して * 展開」というのと同様に

    Hash 生成用のクラスメソッドとして、例えばこんなのがあると便利かも
    しれません(*3)。

    def Hash.map(enum)
    if block_given?
    enum.inject({}) {|h, k| h[k] = yield k; h }
    else
    enum.inject({}) {|h, v| h.store(*v); h }
    end
    end

    ex

    Hash.map(string_keys, &:size) # 文字列 => サイズ
    Hash.map(values.each_with_index) # 値 => インデクス
    Hash.map(other_hash.map {|k, v| [v, k] }) # 値 => キー

他の方の意見やアイデアも聞いてみたいです。

(1)
Google Code Search で「lang:"ruby" inject({}).+;\s
\w+\s*}」
とやったら 2,000 件ヒットしました。

(*2)
http://subtech.g.hatena.ne.jp/cho45/20071128/1196239612 とか
http://d.hatena.ne.jp/takkan_m/20071212/1197466247 とか
http://wota.jp/ac/?date=20081025#p09 とか
某chとか

(*3)
過去、某chに似たようなのを書きこんだのは私です
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0