你如何在 OCaml/ReasonML 中获取列表的一部分?
How do you take a slice of a list in OCaml/ReasonML?
例如,在 Ruby 中,您可以执行以下操作:
list = ["foo", "bar", "baz", "qux", "quux", "corge"]
result = list[2..4]
而 result
将包含 ["baz", "qux", "quux"]
。
在 OCaml/ReasonML 中你会怎么做?
OCaml 切片没有特殊的语言符号。你可以编写你的函数,比如使用模式匹配,或者将 head 与 take 函数结合起来(这些在标准库中可用)。对于 Reason 组合 List.hd 和 List.tk https://reasonml.github.io/api/List.html , also Array module has a sublist Array.sub. The OCaml was discussed here how to get a sub list from a list in ocaml
如果您有权访问 bucklescript 的 Belt
库,您可以执行以下操作:
open Belt;
let myList = ["first", "second", "third", "fourth", "fifth", "sixth"];
/* To get 2..4 */
myList
->List.drop(2)
->Option.getWithDefault([])
->List.take(3)
->Option.getWithDefault([])
->Js.log;
/* Gives you the list ["third", "fourth", "fifth"] */
切片列表没有内置函数,但可以轻松完成。
由于我们有起点和终点,我们可以将问题分解为两部分。第一部分是 drop
几个元素,直到我们到达起点,第二部分是 take
从起点到终点的几个元素。
let rec drop = (n, list) =>
switch (list) {
| [] => []
| [_, ...xs] as z => n == 0 ? z : drop(n - 1, xs)
};
let rec take = (n, list) =>
switch (list) {
| [] => []
| [x, ...xs] => n == 0 ? [] : [x, ...take(n - 1, xs)]
};
现在我们有了这两个函数,我们可以将它们组合起来从开始点开始删除初始元素 drop(i, list)
然后传递这个新列表以从开始点到结束点获取元素
take(k - i + 1, drop(i, list));
共
let slice = (list, i, k) => {
let rec drop = (n, list) =>
switch (list) {
| [] => []
| [_, ...xs] as z => n == 0 ? z : drop(n - 1, xs)
};
let rec take = (n, list) =>
switch (list) {
| [] => []
| [x, ...xs] => n == 0 ? [] : [x, ...take(n - 1, xs)]
};
take(k - i + 1, drop(i, list));
};
更好的方法是先提供起点再提供范围而不是终点,因为这里我们不限制终点应该大于起点
let slice = (list, start, range) => {
let rec drop = (n, list) =>
switch (list) {
| [] => []
| [_, ...xs] as z => n == 0 ? z : drop(n - 1, xs)
};
let rec take = (n, list) =>
switch (list) {
| [] => []
| [x, ...xs] => n == 0 ? [] : [x, ...take(n - 1, xs)]
};
take(range, drop(start, list));
};
如果您有权访问 BuckleScript,您可以使用:
let list = ["foo", "bar", "baz", "qux", "quux", "corge"];
let sliced = Js.Array.slice(~start=2, ~end_=4, list);
中查看更多内容
使用
List.filteri (fun i _ -> i >= start && i <= end)
例如,在 Ruby 中,您可以执行以下操作:
list = ["foo", "bar", "baz", "qux", "quux", "corge"]
result = list[2..4]
而 result
将包含 ["baz", "qux", "quux"]
。
在 OCaml/ReasonML 中你会怎么做?
OCaml 切片没有特殊的语言符号。你可以编写你的函数,比如使用模式匹配,或者将 head 与 take 函数结合起来(这些在标准库中可用)。对于 Reason 组合 List.hd 和 List.tk https://reasonml.github.io/api/List.html , also Array module has a sublist Array.sub. The OCaml was discussed here how to get a sub list from a list in ocaml
如果您有权访问 bucklescript 的 Belt
库,您可以执行以下操作:
open Belt;
let myList = ["first", "second", "third", "fourth", "fifth", "sixth"];
/* To get 2..4 */
myList
->List.drop(2)
->Option.getWithDefault([])
->List.take(3)
->Option.getWithDefault([])
->Js.log;
/* Gives you the list ["third", "fourth", "fifth"] */
切片列表没有内置函数,但可以轻松完成。
由于我们有起点和终点,我们可以将问题分解为两部分。第一部分是 drop
几个元素,直到我们到达起点,第二部分是 take
从起点到终点的几个元素。
let rec drop = (n, list) =>
switch (list) {
| [] => []
| [_, ...xs] as z => n == 0 ? z : drop(n - 1, xs)
};
let rec take = (n, list) =>
switch (list) {
| [] => []
| [x, ...xs] => n == 0 ? [] : [x, ...take(n - 1, xs)]
};
现在我们有了这两个函数,我们可以将它们组合起来从开始点开始删除初始元素 drop(i, list)
然后传递这个新列表以从开始点到结束点获取元素
take(k - i + 1, drop(i, list));
共
let slice = (list, i, k) => {
let rec drop = (n, list) =>
switch (list) {
| [] => []
| [_, ...xs] as z => n == 0 ? z : drop(n - 1, xs)
};
let rec take = (n, list) =>
switch (list) {
| [] => []
| [x, ...xs] => n == 0 ? [] : [x, ...take(n - 1, xs)]
};
take(k - i + 1, drop(i, list));
};
更好的方法是先提供起点再提供范围而不是终点,因为这里我们不限制终点应该大于起点
let slice = (list, start, range) => {
let rec drop = (n, list) =>
switch (list) {
| [] => []
| [_, ...xs] as z => n == 0 ? z : drop(n - 1, xs)
};
let rec take = (n, list) =>
switch (list) {
| [] => []
| [x, ...xs] => n == 0 ? [] : [x, ...take(n - 1, xs)]
};
take(range, drop(start, list));
};
如果您有权访问 BuckleScript,您可以使用:
let list = ["foo", "bar", "baz", "qux", "quux", "corge"];
let sliced = Js.Array.slice(~start=2, ~end_=4, list);
中查看更多内容
使用
List.filteri (fun i _ -> i >= start && i <= end)