【问题标题】:SML: get index of item in listSML:获取列表中项目的索引
【发布时间】:2013-07-24 05:40:23
【问题描述】:

我是 SML 的新手,我正在尝试获取列表中某个项目的索引。我知道使用 List.nth 会给我一个项目在索引位置的值,但我想要索引值。甚至可能有一个我不知道的内置函数。在我的情况下,列表将不包含重复项,因此如果该项目在列表中,我将获得索引,否则返回 ~1。这是我到目前为止的代码。它有效,但我认为它不是很干净:

val L=[1,2,3,4,5];
val m=length L-1;
fun Index(item, m, L)=if m<0 then ~1 else
    if List.nth(L, m)=item then m else Index(item,m-1,L);

【问题讨论】:

  • 您的问题到底是什么?我相信没有标准函数可以明确地做到这一点,至少在 List 结构中没有。至于清理代码,我建议 1) 使用 Option 或异常而不是返回 ~1,2) 通过将函数包装在外部函数中来隐藏参数 m,3) 在 m 上使用模式匹配消除一个条件 (if m &lt; 0 ...)
  • 感谢您的提示。问题实际上是,“最好的方法是什么?”。最好不要将 m 传递给函数,因为它取决于 L 的长度,但就像我说的那样,我是 SML 的新手,不知道如何将两者结合起来。代码的原因是;我有两个相关的不同类型的列表。更新列表一中的项目需要更新列表二中相同位置的项目。我相信 List 结构可能会通过“zip”提供类似的东西,但现在可以使用。

标签: list indexing sml


【解决方案1】:

为了详细说明我之前的评论,我建议对更适合 ML 习语的实现进行一些更改:

fun index(item, xs) =
  let
    fun index'(m, nil) = NONE
      | index'(m, x::xr) = if x = item then SOME m else index'(m + 1, xr)
  in
    index'(0, xs)
  end

个别变化是:

  • index 返回一个int option 类型的值。 NONE 表示该项目不在列表中,SOME i 表示它在列表中,其第一次出现的索引为i。这样,就不需要使用特殊值 (~1),并且可以从函数的类型推断出函数的预期用途。
  • 隐藏参数m,方法是将函数重命名为index',并将其包装到外部函数index 中,该函数使用适当的参数调用它。 素数字符 (`) 通常表示辅助值。
  • 使用列表中的模式匹配来获取各个元素,无需使用List.nth

还请注意,最常见的函数和变量名称以小写字母开头(index 而不是 Index),而大写字母用于构造函数常量(一些)等等。

【讨论】:

  • 感谢您的详尽解释。我在 SO 中多次看到这个成语,无法理解用相同名称命名内部和外部函数的目的。我试图用谷歌搜索它,但很难搜索到你不知道它叫什么的东西。再次感谢! :)
【解决方案2】:

我想提出这个index 函数的一个更简单、效率更低的版本。我同意使用异常而不是int option 是不可取的,并且它不是尾递归的。但它肯定更容易阅读,因此可以作为学习材料:

fun index (x, []) = raise Subscript
  | index (x, y::ys) =
    if x = y then 0 else 1 + index (x, ys)

【讨论】:

    【解决方案3】:
    fun index(list,n)=
    = if n=0 then hd(list) else index(tl(list),n-1);
    val index = fn : 'a list * int -> 'a
    
    index([1,2,3,4,5],2);
    val it = 3 : int
    
    index([1,2,3,4,5],0);
    val it = 1 : int
    

    【讨论】:

    • 仅代码的答案在本网站上通常不受欢迎。您能否编辑您的答案以包含一些 cmets 或对您的代码的解释?解释应该回答这样的问题:它有什么作用?它是如何做到的?它去哪儿了?它如何解决OP的问题?请参阅:How to anwser。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-06-15
    • 2013-04-29
    • 2019-01-25
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多