如何在Clojure中向量的向量上迭代? [英] How do I iterate over a vector of vectors in Clojure?

查看:170
本文介绍了如何在Clojure中向量的向量上迭代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含3个属性的邮件:类型,货币和金额。



我有一个规则,包含4个属性,目的地,邮件类型,一个金额。



我想通过我的规则,找到匹配的消息类型的消息,并返回目的地,或null如果没有匹配

我使用一个向量作为消息和规则中字段的固定位置,我已将它们定义如下:

  user => (def msg [100,USD,100])
#'user / msg

user => (def rules [[FAL100UKP100] [FBC101USD100]])
#'user / rules

然后我定义一些从规则和消息中提取消息类型的函数:

  user =>(defn rule-mt [[_ mt]] mt)
#'user / rule-mt

user =>(defn msg-mt [[mt]] mt)
#'user / msg-mt



定义一个匹配消息类型的函数,如下所示:

  user =>(defn match-mt [msg rule](= (rule-mt rule)(msg-mt msg)))
#'user / match-mt


$ b b

所以我可以直接调用如下,检查它是否符合第一条规则:

  user => match-mt msg(rules 0))
true

第二条规则:

 (match-mt msg(rules 1))
false

如何迭代我的规则(向量矢量)调用我的匹配函数,然后返回匹配规则的目标字段第一个字段的规则)?

解决方案

只要这样做!这里有一个解决方案,使用查找匹配消息的所有规则,然后使用首先返回第一个 。但是由于懒惰,只需要计算一个成功的匹配。

 (defn dest-of-rule [rule]规则))
(defn get-dest [msg]
(第一个
(对于[r rules
:when(match-mt msg r)]
-of-rule r))))

这里有一个替代解决方案使用filter: / p>

 (defn get-dest [msg] 
(dest-of-rule msg%)rules))))

c> + filter idiom是很常见的,这就是为什么有一个名字: find-first 。它是可用的。在包seq-utils中(请参阅此处)。 p>

I have a message with 3 attributes: type, currency and amount.

I have a rule with 4 attributes, a destination, a message type, a currency and an amount.

I want to go through my rules and find a match to the message on the message type and return the destination, or null if there was no match

I'm using a vector for the fixed positions of the fields in the message and rule, I've defined them as follows:

user=> (def msg [100, "USD", 100])
#’user/msg

user=> (def rules [["FAL" 100 "UKP" 100] ["FBC" 101 "USD" 100]])
#’user/rules

Then I define some functions that extract the message type from a rule and a message:

user=>(defn rule-mt [[_ mt]] mt)
#’user/rule-mt

user=>(defn msg-mt [[mt]] mt)
#’user/msg-mt

I've defined a function to match the message types as follows:

user=>(defn match-mt [ msg rule ] ( = ( rule-mt rule ) ( msg-mt msg ) ) )
#’user/match-mt

So I can call this directly as follows to check if it matches the first rule:

user=>(match-mt msg (rules 0))
true

And then to see if it matches the second rule:

(match-mt msg (rules 1))
false

How do I iterate over my rules (vector of vectors) calling my match function and then return the destination field of a matching rule (the first field of the rule) ?

解决方案

Just do it! Here's a solution that finds all the rules that match a message using a for and then returns the first of them using first. However because of laziness, only one succesful match needs to be computed.

(defn dest-of-rule [rule] (first rule))
(defn get-dest [msg]
   (first
      (for [r rules
            :when (match-mt msg r)]
         (dest-of-rule r))))

Here's an alternative solution that does the same using filter:

(defn get-dest [msg]
   (dest-of-rule (first (filter #(match-mt msg %) rules))))

The first + filter idiom is very common and that's why there's a name for it: find-first. It is available e.g. in the package seq-utils (see here).

这篇关于如何在Clojure中向量的向量上迭代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆