LoginSignup
0
0

More than 1 year has passed since last update.

[py2rb] itemgetter

Last updated at Posted at 2022-01-28

はじめに

移植やってます。
( from python 3.7 to ruby 2.7 )

itemgetter (Python)

def itemgetter(*items):
    if len(items) == 1:
        item = items[0]
        def g(obj):
            return obj[item]
    else:
        def g(obj):
            return tuple(obj[item] for item in items)
    return g

>>> itemgetter(1)('ABCDEFG')
'B'
>>> itemgetter(1,3,5)('ABCDEFG')
('B', 'D', 'F')
>>> itemgetter(slice(2,None))('ABCDEFG')
'CDEFG'
>>> soldier = dict(rank='captain', name='dotterbart')
>>> itemgetter('rank')(soldier)
'captain'

便利なのかも。

def (Ruby)

def itemgetter(obj, *items)
  if items.size == 1
    item = items[0]
    def g(obj, *items)
      item = items[0]
      return obj[item]
    end
  else
    def g(obj, *items)
      return items.map{ |item| obj[item] }
    end
  end
  return g(obj, *items)
end

p itemgetter('ABCDEFG', 1)
p itemgetter('ABCDEFG', 1, 3, 5)
p itemgetter('ABCDEFG', 2..)
soldier = {'rank' => 'captain', 'name' => 'dotterbart'}
p itemgetter(soldier, 'rank')

# output
"B"
["B", "D", "F"]
"CDEFG"        
"captain"  

引数の順番を合わせるようにブロックを使用した方がかっこいいかもしれないのですが。

lambda (Ruby)

ig1 = lambda { |x| x[1] }
ig2 = lambda { |x| [1, 2, 3].map{ x[_1] } }
ig3 = lambda { |x| (2..x.size.pred).map{ x[_1] }.join('') }
soldier = {'rank' => 'captain', 'name' => 'dotterbart'}
ig4 = lambda { |x| soldier[x] }

p ig1.call('ABCDEF')
p ig2.call('ABCDEF')
p ig3.call('ABCDEF')
p ig4.call('rank')

# output
"B"
["B", "C", "D"]
"CDEF"
"captain" 

一つ目の引数と二つ目の引数が同時に呼ばれない様なので、こういうのもありかも。

class (Ruby)

class Itemgetter
  def initialize(*items)
    if items.size == 1
      @item = items[0]
    else
      @items = items
    end
  end

  def g(obj)
    if @item
      obj[@item]
    else
      @items.map{ |item| obj[item] }
    end
  end
end

ig1 = Itemgetter.new(1)
ig2 = Itemgetter.new(1, 2, 3)
ig3 = Itemgetter.new(2..)
ig4 = Itemgetter.new('rank')

p ig1.g('ABCDEF')
p ig2.g('ABCDEF')
p ig3.g('ABCDEF')
soldier = {'rank' => 'captain', 'name' => 'dotterbart'}
p ig4.g(soldier)

# output
"B"
["B", "C", "D"]
"CDEF"
"captain" 

クラスの方がスッキリかな。

メモ

  • Python の itemgetter を学習した
  • 百里を行く者は九十里を半ばとす
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0