简体   繁体   English

如何清理特定字符串的列表并返回清理后的列表或无

[英]How to clean a list for a specific string and return the cleaned list or NONE

I need to write a function to answer these specifications: 我需要编写一个函数来回答这些规范:

clean_list( [],s1] = NONE

clean_list( xs, "") = NONE

clean_list ([s1, s1, s1, s1], s1) = NONE

clean_list([s1, s2, s3, s2, s1], s3) = [s1, s2, s2, s1]

where s1 , s2 , s3 are some strings and xs a list of strings. 其中s1s2s3是一些字符串,而xs是字符串列表。

I was able to do it using the two helper functions is_into(xs: string list, s1: string) -> bool and remove(xs: string list, s1: string) -> string list but it seems ugly to recurse twice through the list. 我能够使用两个辅助函数is_into(xs: string list, s1: string) -> boolremove(xs: string list, s1: string) -> string list做到这一点,但是通过两次递归两次似乎很难看清单。

clean_list(xs: string list, s1: string) =
    case (xs, s1) of
         ( [], _ ) => NONE
        |( _, "" ) => NONE
        |( _, _) => if is_into(xs, s1)
                    then remove(xs, s1)
                    else NONE

Is there a way to do it without recursing in the list twice (once in is_into and once in remove )? 有没有一种方法可以做到而又不在列表中is_into两次(一次在is_into ,一次在remove )?

Note: None of builtin functions are to be used. 注意:不使用任何内置函数。

Sorry i forgot an important case in the specifications 对不起,我忘记了规格中的重要案例

clean_list ([s1, s2, s3, s4], s10] = NONE

Your clean_list function doesn't typecheck since some branches have type 'a option and others have type 'b list . 您的clean_list函数不会进行类型检查,因为某些分支的类型为'a option而另一些分支的类型为'b list

Assuming you would like to return 'b list , NONE should be replaced by [] . 假设您想返回'b list ,则NONE应该替换为[] You can use pattern matching recursively on clean_list to avoid the need of auxiliary functions: 您可以在clean_list上递归使用模式匹配,以避免需要辅助功能:

fun clean_list(xs: string list, s1: string) =
    case (xs, s1) of
      ([], _) => []
    | (_, "") => []
    | (x::xs', _) => if x = s1 
                     then clean_list(xs', s1)
                     else x::clean_list(xs', s1)

You can easily go through the list once, element by element and removing all that matches the given string, returning SOME lst at the end, where lst is the resulting list 您可以轻松地一次遍历该列表,逐个元素地删除所有与给定字符串匹配的列表,最后返回SOME lst ,其中lst是结果列表

fun clean_list ([], _ ) = NONE
  | clean_list (_, "") = NONE
  | clean_list (xs, str) =
    let
      fun clean_list' [] = []
        | clean_list' (x::xs) =
          if x = str then
            clean_list' xs
          else
            x :: clean_list' xs
    in
      SOME (clean_list' xs)
    end

Update 更新资料

I noticed that the above code actually doesn't handle the case: clean_list ([s1, s1, s1, s1], s1) = NONE . 我注意到上面的代码实际上无法处理这种情况: clean_list ([s1, s1, s1, s1], s1) = NONE However this is an easy fix. 但是,这很容易解决。

I can see that given your new updated specification, that if the element is not in the list in the first place, then NONE should be returned. 我可以看到,给定新的更新规范,如果该元素不在列表的首位,则应该返回NONE This is the same as saying, if no elements was removed while going through all the elements, then return NONE . 这与说相同,如果遍历所有元素时未删除任何元素,则返回NONE

Hopefully you can see that this can be implemented by added an extra Boolean argument to the helper function, initially setting it to false, and then passing along its value in each recursive call, except in the case where an element is removed, here it can always be set to true. 希望您可以看到可以通过在辅助函数中添加一个额外的布尔参数,将其初始设置为false,然后在每次递归调用中传递其值来实现,除非除去了元素,在这里它可以始终设置为true。

This can then be used to determine weather to return the SOME lst , where lst is the resulting list, or NONE if no elements was removed. 然后可以将其用于确定返回SOME lst天气,其中lst是结果列表,如果未删除任何元素,则返回NONE

Given these two things, that needs to be fixed, it would probably bee a good idea to have the helper function built up its result in an accumulating argument, instead. 考虑到这两个问题,需要修复,因此最好将助手函数的结果建立在一个累加的参数中,这可能是一个好主意。 This way you have full control and can easily return NONE when the accumulating list is empty at the end. 这样,您可以完全控制,并且当累加列表最后为空时,可以轻松返回NONE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM