狠狠撸
Submit Search
厂尘补濒濒迟补濒办で文字列解析?集计
?
0 likes
?
895 views
M
Masashi Umezawa
Follow
CROSS 2014 「言語CROSS」でのF#お題「カレーのメニュー解析&集計」の解答です
Read less
Read more
1 of 13
Download now
Download to read offline
More Related Content
厂尘补濒濒迟补濒办で文字列解析?集计
1.
CROSS 2014 言語CROSS Smalltalkによる カレー問題別解解説 2014 SoftUmeYa,
LLC Masashi Umezawa
2.
カレーのお題 長いので略。以下のような文字列をパース 1;パリパリチキン;肉類;500;0; 2;ロースカツ;肉類;300;0;なす,ゆでタマゴ 3;海の幸;魚介類;300;1; 4;やさい;野菜類;400;0;ゆでタマゴ ...
3.
解答の方針 ?関数型言語っぽく書く ブロッククロージャやコレクション系の プロトコルを駆使 変数の代入は極力避ける ちょっとやり過ぎでアレな感じにする 結構まともになった... ? Smalltalk for
Lispers – http://live.exept.de/doc/online/english/programming/stForLi spers.html クロージャ駆使はSmalltalk的スタイル
4.
getOrderHistory ? 「関数を定義」とあるので、全体をクロージャに 注文クラスを導入せず、辞書を返している getOrderHistory :=
[:src | | rows rowStream | rows := OrderedCollection new. rowStream := src readStream. [rowStream atEnd] whileFalse: [rows add: ((rowStream nextLine) findTokens: ';')]. rows collect: [:eachRow | Dictionary new in: [:map | #(#OrderId #CurryMenu #Category #RiceWeight #HotFlavor #Toppings) paddedWith: eachRow do: [:a :b | map add: (a->b)]. map] ]. ].
5.
A1 ? 「辛さ」が2以上の注文を抽出し、 その「注文 ID」をすべて取得せよ 注文についてのクラスを導入せず、辞書を返している orders
:= getOrderHistory value: source. orders select: [:each | (each at: #HotFlavor) asInteger >= 2] thenCollect: [:each | each at: #OrderId].
6.
A2 ? 「分類」ごとに「ライスの量」の平均を取得せよ。 なお、平均値が大きい順に並べる ((orders groupBy:
[:each | (each at: #Category)] having: [:each | true]) collect: [:each | (each collect: [:e | e at: #RiceWeight]) average]) associations sorted: [:a :b | a value > b value]
7.
A3 ? 「メニュー」がロースカツの注文について、 各「トッピング」の出現回数をカウント Bag new
in: [:bag | (orders select: [:each | (each at: #CurryMenu) = 'ロースカツ']) do: [:each | (each at: #Toppings) ifNotNil:[:toppings | bag addAll: (toppings findTokens: ',')]]. bag sortedElements]
8.
F-like ?もう少し工夫してみる 括弧が多いのはいかがなものか F#のパイプライン演算子(|>)は、やはり綺麗
9.
パイプラインの実装(1) ? >> というメソッドをBlockClosureに定義 >>
otherBlock ^ otherBlock value: self value ? Objectにも定義 >> other ^ [self] >> other
10.
パイプラインの実装(2) ? BlockClosureにselectやらcollectを定義 collect ^ [:col
| col collect: self] select ^ [:col | col select: self] 同様に、gather, sortedも用意 ? できた!!
11.
A1 ? 「辛さ」が2以上の注文を抽出し、 その「注文 ID」をすべて取得せよ 注文についてのクラスを導入せず、辞書を返している orders
:= getOrderHistory value: source. orders >> [:each | (each at: #HotFlavor) asInteger >= 2] select >> [:each | each at: #OrderId] collect.
12.
A2 ? 「分類」ごとに「ライスの量」の平均を取得せよ。 なお、平均値が大きい順に並べる (orders groupBy:
[:each | (each at: #Category)] having: [:each | true]) >> [:each | (each collect: [:e | e at: #RiceWeight]) average]) collect >> #associations >> [:a :b | a value > b value] sorted
13.
A3 ? 「メニュー」がロースカツの注文について、 各「トッピング」の出現回数をカウント (orders select: [:each
| (each at: #CurryMenu) = 'ロースカツ']) >> [:each | (each at: #Toppings) ifNil:[#()] ifNotNil: [:toppings | (toppings findTokens: ',')]] collect >> [:each | each] gather >> #asBag >> #sortedElements
Download