在向量上使用过滤器

时间:2018-09-15 20:19:51

标签: clojure clojure-java-interop

我试图在filter的向量上使用dataset函数,该向量的定义如下:

AK,0.89,0.98
AR,0.49,0.23
AN,0.21,0.78
...

我想获取包含某个字符串的所有值,如下所示:

(filter (contains "AK") dataset)

哪个会返回:

AK,0.89,0.98

是否可以使用过滤器功能来做到这一点? 我已经使用剂量q遍历了向量,但是我必须在代码中的某些时候使用filter。 谢谢:)

1 个答案:

答案 0 :(得分:2)

基本答案是肯定的,您可以使用过滤器执行此操作。过滤器期望 谓词函数,即返回true或false的函数。过滤器 函数将遍历您传入和传递的集合中的元素 从该集合到谓词的每个元素。你在里面做什么 谓词功能完全取决于您(尽管您应确保避免 副作用)。过滤器将收集谓词返回的所有元素 进入新的惰性序列。

基本上,您有(长格式)

(filter (fn [element] 
         ; some test returning true/fals) col)

col是您的收藏集。结果将是元素的LAZY SEQUENCE 谓词函数返回true的位置。重要的是要了解 诸如filter和map之类的东西会返回惰性序列,并且知道真正的含义。

要理解的关键是集合的结构。在你的 您说过的说明

  

我正在尝试在称为数据集的向量上使用过滤器功能   定义如下:

     

AK,0.89,0.98 AR,0.49,0.23 AN,0.21,0.78 ...

很遗憾,您的描述有点含糊。如果您的数据集结构 实际上是向量的向量(不仅仅是向量),那么事情就非常 直截了当。这是因为这意味着将每个“元素”传递给 谓词函数将是您的“内部”向量之一。真正的定义是 更准确地表示为

[
 [AK,0.89,0.98]
 [AR,0.49,0.23]
 [AN,0.21,0.78]
 ...
]

要传递给谓词的是3个元素的向量。如果你只想 选择第一个元素为“ AK”的所有向量,然后谓词 功能可能就像

(fn [el]
 (if (= "AK" (first el))
   true;
   false))

所以整行就像

(filter (fn [el]
         (if (= "AK" (first el))
           true
           false)) [[AK 0.89 0.98] [AR 0.49 0.23] [AN 0.21 0.78]])

这只是开始,非常冗长。您可以做很多事情 使其更短例如。

(filter #(= "AK" (first %)) [..])

如果另一方面,您实际上确实只有一个向量,则事情 变得有点复杂,因为您需要以某种方式将 价值观。这可以通过使用分区功能来分解您的 向量分成3个项目的组,然后再将其传递给过滤器,例如

(filter pred (partition 3 col))

会将原始向量中的元素分为3组并通过 每个组都有谓词功能。这就是地图的真正力量所在 过滤,缩小等发挥作用-您可以转换数据,传递数据 通过一系列功能,每个功能都以某种方式操纵数据并 最终结果弹出。

关键是要了解什么过滤器(以及其他类似这样的功能,例如 例如map或reduce)将被理解为输入中的“元素” 采集。基本上,这与“ first”将返回的内容相同 呼吁收集。这就是传递给的谓词函数 归档器。

这里有很多假设。主要之一是您的数据是 严格排序,即您要测试的值始终是第一个 每个组中的元素。如果不是这种情况,则需要做更多的工作 完成。同样,我们假设数据总是以3为一组。如果不是,则将需要其他方法。