例如,在Ruby中,您可以执行以下操作:
list = ["foo", "bar", "baz", "qux", "quux", "corge"]
result = list[2..4]
并且result
将包含["baz", "qux", "quux"]
。
您将如何在OCaml / ReasonML中执行此操作?
没有内置的切片列表功能,但可以轻松完成。由于我们有一个起点和一个终点,因此可以将问题分为两部分。第一部分是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));
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句