私はzipWith
2つのシーケンスの対応する要素を操作する標準関数に精通していますが、関数型言語(またはいくつかの関数型機能を備えた言語)では、に基づいて、圧縮する要素のペアを条件付きで選択する最も簡潔な方法は何ですか? 3番目のシーケンス?
この好奇心は、Excelでいくつかのことをスクラッチしているときに発生しました。
A1:A10、B1:B10、C1:C10、D1、E1、F1の数字で、次のような式を使用しています。
{=AVERAGE(IF((D1<=(A1:A10))*((A1:A10)<=E1),B1:B10/C1:C10))}
IFステートメントの乗算の各半分は、ブール値の配列を生成し、それらは一緒に乗算(AND)されます。これらのブール値は、10個の商のどれが最終的に平均化されるかを制御するため、10個の個別のIFステートメントが評価されているかのようになります。
たとえば、A1:A10の10個の値の2番目と3番目だけが条件(> =D1と<=E1の両方)を満たす場合、式は次のように評価されます。
AVERAGE(FALSE,B2/C2,B3/C3,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE)
AVERAGE関数はたまたまブール値とテキスト値を無視するため、2番目と3番目の商の平均を取得するだけです。
これはHaskellで簡潔に行うことができますか?Erlang?LINQまたはF#?Python?等..
この特定の例では、上記の式が完全に正しいわけではないことに注意してください。基本的なポイントを理解するために省略されています。A1:A10の10個の要素のいずれも条件を満たさない場合、10個のFALSE値がAVERAGEに渡され、誤って0と評価され
ます。式は次のように記述する必要があります。
{=AVERAGE(IF(NOT(OR((D1<=(A1:A10))*((A1:A10)<=E1))),NA(),
IF((D1<=(A1:A10))*((A1:A10)<=E1),B1:B10/C1:C10)))}
NA()
がエラーを生成し、平均が未定義であることを示します 。
アップデート:
答えてくれてありがとう。最初のリストの対応する要素が特定の基準を満たしている場合に、2番目と3番目のリストの要素のペアに関数を適用するという点で、最初の質問は非常に簡単であることに気付きました。そのためのノーマン・ラムゼーの答えを受け入れました。
しかし、次に行ったのは、任意の数のリストからの対応する要素を表すタプルに関数を適用できるかどうか疑問でした。したがって、の制限についてLebertramに質問しましたzipWithN
。
適用可能なファンクターに関するApocalispの情報から、Pythonによる引数リストの解凍(任意の数の引数に関数を適用する)に関する情報が得られました。
上記の特定の例では、リストの要素の商を平均すると(nums
リストのリストはここにあります)、Pythonは次のように実行できるように見えます。
from operator import div
def avg(a): return sum(a,0.0)/len(a)
avg([reduce(div,t[1:]) for t in zip(*nums) if d<=t[0] and t[0]<=e])
より一般的には、関数f
と述語p
(およびavg
)を使用すると、これは次のようになります。
avg([f(t[1:]) for t in zip(*nums) if p(t[0])])