clojure - 如何打破 Clojure 中的 for 循环?
问题描述
我有以下功能:
(defn next-transformation
[arr]
(let [
arr-len (count arr)
i-range (range 0 arr-len)
j-range (range 0 arr-len)
indexes (for [i i-range
j j-range]
(let [
xi (nth arr i)
xj (nth arr j)
]
(if (> xi xj)
[i j]
nil
)
)
)
non-nil-indexes (filter
(fn [elem]
(not (= elem nil))
)
indexes
)
]
(if (not (empty? non-nil-indexes))
(first non-nil-indexes)
nil
)
)
)
它返回元组数组的第一个元素,元组[i j]
描述数组arr
中arr[i] > arr[j]
为真的元素。
下面for
片段中的循环遍历每一对 i 和 j:
indexes (for [i i-range
j j-range]
(let [
xi (nth arr i)
xj (nth arr j)
]
(if (> xi xj)
[i j] ;; I want the loop to stop here
nil
)
)
)
如何修改这个 for 循环,使其在找到第一个相关元组后停止(即循环应该在标有;; I want the loop to stop here
注释的地方停止)?
这是Java中的等效代码:
private Integer[] next-transformation(final Integer[] arr) {
for (int i=0; i < arr.length; i++) {
for (int j=0; j < arr.length; j++) {
if (arr[i] > arr[j]) {
return new Integer[] {i, j};
}
}
}
}
更新1:
正如@CharlesDuffy 推荐的那样,我for
用loop
/替换了recur
:
(defn next-transformation
[arr]
(loop [i 0
j 0]
(let [
arr-len (count arr)
]
(if (and (< i arr-len)
(< j arr-len))
(let [
xi (nth arr i)
xj (nth arr j)
j-plus-1 (+ j 1)
i-plus-1 (+ i 1)
new-i (if (< j-plus-1 arr-len)
i
(+ i 1))
new-j (if (< j-plus-1 arr-len)
(+ j 1)
0)
]
(if (> xi xj)
;; We found it
[i j]
;; We haven't found it, recur
(recur new-i new-j)
)
)
nil ; We are at the end of the loop
) ; if
)
) ; loop
) ; defn
解决方案
在for
列表推导中,用于:when
过滤感兴趣的元组,并用于first
仅返回第一个:
(defn next-transformation [arr]
(first (for [i (range (count arr))
j (range (count arr))
:when (> (nth arr i) (nth arr j))]
[i j])))
推荐阅读
- angularjs - Angular 8.2.14 中 coreJS 的合适版本
- javascript - 网页上的 JSON 格式
- swift - 在不丢失先前格式的情况下更新属性字符串
- c# - Bot Framework v4 c# - 如何保存用户和聊天机器人之间的整个聊天对话
- javascript - 用于特定下载项 ID 的 chrome.downloads.erase 突然关闭 chrome
- html - 用于 FlexBox 的内联 fxFlex 既不会让子代匹配容器,也不会对齐子代
- windows - 在 Windows 10 上安装 PostgreSQL 版本 12.4 时出现问题
- php - 高级自定义字段/Wordpress - 为什么我的帖子对象在循环内显示为空白?
- c# - 将 SQL 转换为 LINQ 查询 C# mvc
- string - 批量查找给定字符串条件的文件