事例:入れ子になったリストを平坦化する

平坦化したリストが得られます *1

def asSequence(s):
    if isinstance(s, list):
        return reduce(lambda acc,c: acc+asSequence(c), s, )
    else:
        return [s]

def flatten(s):
    return reduce(lambda acc,c: acc+asSequence(c), s, )
>>> s = [1,[2,3],[4,[5,6]]]
>>> flatten(s)
[1, 2, 3, 4, 5, 6]

リストの要素にリストを含むような、入れ子構造になったリストをもとに、各要素を列挙しただけの平坦化(分配的連接 *2)したリストが得られます。


《Note》OCL では、次のような制約が規定されています。

flatten(): Sequence(T2) 
post: result =
  if self.type.elementType.oclIsKindOf(CollectionType) then 
    self->iterate(c; acc: Sequence() = Sequence{} | 
      acc->union(c->asSequence() ) ) 
  else 
    self 
  endif


iterate 操作を利用すると、簡潔で見通しの良い記述が可能になります。□

*1:Smalltalk 3分クッキング《問7》リストの平坦化, 1988.

*2:《参考文献》conc/The VDM++ Language/4.2.2 Sequence Types