- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将词性函数的输出通过管道传输到索引词函数中,并使用 (->) 线程宏打印结果输出:
(defn parts-of-speech []
(seq (. POS values)))
(defn index-words [pos]
(iterator-seq (. dict getIndexWordIterator pos)))
(-> (parts-of-speech) index-words println)
但是索引词函数返回一个迭代器序列,我不确定如何在这种情况下迭代它,因为我是 Clojure 的新手。
编辑:根据建议更新代码。
更新:
感谢@kotarak 和@jayunit100 的回答以及@sw1nn 和@marko-topolnik 的评论,我至少有两个变体可以工作:
(->> (parts-of-speech) (map index-words) (map println) doall)
(doseq [w (map index-words (parts-of-speech))]
(println w))
我来自命令式背景,我的这个问题的目标是理解线程宏,以尝试编写更惯用的 Clojure(在尝试线程宏之前,我使用多个 doseq
和let
秒)。
从评论来看,线程宏似乎不是执行此操作的最惯用的方法,但我仍然想看看如何让它工作,以便填补理解上的空白。
此外,(parts-of-speech)
返回一个包含四个项目的序列,如果您执行 (println (count w))
而不是 (println w)
,您可以看到它打印四个序列的计数而不是一个连续序列:
(doseq [w (map index-words (parts-of-speech))]
(println (count w)))
;= 117798
;= 11529
;= 21479
;= 4481
您将如何修改上面的内容以打印一个连续的单词流而不是打印四个序列的内容?
顺便说一句:上面的代码包装了 MIT Java WordNet 库 ( http://projects.csail.mit.edu/jwi/ )。
最佳答案
seqs 和 iterator-seq 之间的关系如下:一个 iterator-seq 从一个迭代器创建一个 seq。
请原谅这里的冗长,但要回答“如何迭代 iterator-seq 的输出”这个问题,我们必须首先明确定义为什么需要调用 iterator-seq 开始:
在 Clojure 中,您不会发现自己需要太频繁地创建 iterator-seq 对象。由于 clojure 可以非常方便地处理“可迭代”Java 对象的迭代(参见:http://clojuredocs.org/clojure_core/clojure.core/iterator-seq)。然而,迭代器本身是不可迭代的。
要完全理解这一点,您需要了解 Iterables 和 Iterators 之间的区别,这主要是由于在 Java 世界中保持语义一致和直接:Why is Java's Iterator not an Iterable? .
那么什么是“seq”?
在clojure中有一个比java的Iterator接口(interface)更高的抽象,就是ISeq。 iterator-seq 在底层为我们创建了一个 ISeq。这个 ISeq 对象现在可以被许多针对顺序项目列表操作的 Clojure 函数使用。
user=> (iterator-seq (.iterator (new java.util.ArrayList ["A" "B"])))
("A" "B")
;Thus, we now have an ISeq implementation derived from an iterator.
因此,您的“iterator-seq”函数正在为您创建一个来自 java 迭代器的 Clojure“序列”。澄清一下——当我们在不可迭代对象上调用“iterator-seq”时的错误消息是信息性的:
user=> (iterator-seq "ASDF")
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Iterator (NO_SOURCE_FILE:0)
这告诉我们“iterator-seq”函数需要一个 java.util.Iterator 作为输入。
您可能有的下一个合乎逻辑的问题是:
为什么我们需要从迭代器创建序列? seq 抽象与 java 中的迭代器抽象有何不同?
Iterable 接口(interface)不像 Clojure 的 ISeq 那样抽象。例如,考虑字符串。显然,字符串是连续的。然而,它们在 Java 中不可迭代。数组也是如此。
来自 clojure 网站:
“seq 适用于 Java 引用数组、Iterables 和字符串。由于库的其余大部分都是基于这些函数构建的,因此在 Clojure 算法中使用 Java 对象得到了很好的支持。”
因此,您的 iterator-seq 的目的是将您的迭代器对象“包装”到一个序列抽象中,这将能够利用所有 clojures 功能好东西。
定义iterator-seq的作用
来自 http://clojure.org/sequences :
“seq 函数产生适合集合的 ISeq 实现。”
在您的情况下,我们可以这样说:
“iterator-seq 函数为您的 getIndexWordsIterator 生成 ISeq 的实现”。
最后:如何迭代序列?
这个问题需要根据上下文仔细回答。
迭代当然是可能的 - 但不是 clojure 中的主要关注点,它可能不是您真正想要的。由于 iterator-seq 已经为我们创建了一个 SEQ,现在我们可以使用 Clojure 的函数运算符之一(即在列表理解、映射函数等中)来使用该 seq。这避免了手动迭代的需要。
例如,我们经常遍历列表以查找值。在 Clojure 中,我们可以通过以下方式找到一个值使用过滤功能:
user=> (filter #(= \A %) (seq "ABCD"))
(\A)
不是过滤,我们可能希望通过遍历每个对象将函数应用于多个对象,并将结果存储在新集合中。同样,这不需要通过 Clojure 中的显式迭代来完成:
user=> (map #(.hashCode %) (seq "ABCZ"))
(65 66 67 90)
最后,如果你真的需要手动遍历你的集合,你可以使用 Loop-recur 构造来手动,尾递归地遍历你的序列,一次一个元素:http://clojure.org/functional_programming#Functional%20Programming--Recursive%20Looping .或者您可以使用标准递归调用。
关于java - 如何使用 -> (thread) 宏来传递 Clojure iterator-seq?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10275321/
我正在尝试表达以下内容: 给定一个矩阵和两个索引增量,返回矩阵中所有数字的四倍体:沿行,列或对角线的四倍体。 use std::iter::Iterator; use std::iter::Peeka
假设我们有以下类组成角色 Iterable : class Word-Char does Iterable { has @.words; method !pairize($item)
我编写了一个 ADT 排序二叉树,其功能如下: public Iterator getInorderIterator(){ return new InorderIterator(); } 有效
在包装(内部)迭代器时,通常必须将 __iter__ 方法重新路由到底层可迭代对象。考虑以下示例: class FancyNewClass(collections.Iterable): def
尽管如此,我遍历了以下 NSSet , NSMutableArray , NSFastEnumeration文档,我找不到下面提到的场景的令人满意的来源: 此处,NSMutableArray、NSAr
我发现在 Python 中 collections.Iterable 和 typing.Iterable 都可以用于类型注释和检查对象是否可迭代,即 >isinstance(obj, collecti
我想拆分实现 Iterator 的对象的输出分为两个实现 Iterator 的对象和 Iterator .由于其中一个输出的迭代次数可能比另一个多,因此我需要缓冲 Iterator 的输出。 (因为我
我正在尝试用 Rust 编写一个简单的迭代器: #[derive(Debug)] pub struct StackVec { storage: &'a mut [T], len: us
什么意思: Separator.Iterator.Element == Self.Iterator.Element.Iterator.Element 在this (Swift 标准库)swift 实例
调用 anIterable.iterator() 会返回新的迭代器还是现有的迭代器?它依赖于 Iterable 的实现吗? 更具体地说,以下代码是否按预期工作(即内部循环将从头开始迭代)? for (
我正在尝试转换 &str 的矢量对成一个 HashMap使用以下代码片段: use std::collections::HashMap; fn main() { let pairs = vec!(
这将使安全地迭代同一元素两次成为可能,或者为在项目类型中迭代的全局事物保持某种状态。 类似于: trait IterShort where Self: Borrow, { type I
我在 String 的字符上使用迭代器: pub fn is_yelling(message: &str) -> bool { let letters = message.chars().fi
这将使安全地迭代同一元素两次成为可能,或者为在项目类型中迭代的全局事物保持某种状态。 类似于: trait IterShort where Self: Borrow, { type I
要在 Rust 中实现迭代器,我们只需要实现 next 方法,如 in the documentation 所解释的那样.但是,Iterator 特征 has many more methods .
我正在为多个结构实现 Iterator 特性并遇到了一些问题。为什么为 Rows 实现 Iterator 显示错误?这是一个链接:link to playground 基本上为什么这不起作用? str
我将集合转储到磁盘上。当请求时,应该检索这些集合(没问题)和 iterator应该为它构建返回对检索到的值的引用。 iterator之后被丢弃了,我不再需要收藏了。我也希望它被删除。 到目前为止我尝试
我正在尝试为实现特征的结构实现默认迭代器。我的特征称为 DataRow,代表一行表格单元格,如下所示: pub trait DataRow { // Gets a cell by index
Rust 中是否有提供 iter() 的 Trait方法?我只找到了特征 IntoIterator ,供应into_iter() . 这里要明确一点:我不想要 Iterator特性,提供 next()
我想在迭代器上定义一个 .unique() 方法,使我能够在没有重复的情况下进行迭代。 use std::collections::HashSet; struct UniqueState {
我是一名优秀的程序员,十分优秀!