Kata描述: Western Suburbs槌球俱乐部有两类会员,即高级和公开会员。他们希望您提供申请表格的帮助,告诉潜在会员他们将被安排哪个类别。 成为一名大四学生,成员必须年满55岁,并且有一个大于7的差点。在这个槌球俱乐部,残障从-2到+26;玩家越好障碍越低。 输入 输入将包含一个列表,每个列表包含两个项目。每个列表包含单个潜在成员的信息。信息包括人的年龄的整数和人的差点的整数。 示例输入
[[18, 20],[45, 2],[61, 12],[37, 6],[21, 21],[78, 9]]
输出 输出将包含一个字符串值列表(在Haskell中:Open或Senior),说明相应的成员是放在高级还是开放类别中。 示例输出
["Open", "Open", "Senior", "Open", "Open", "Senior"]
我用三种不同的语言解决了这个答案:Python,C#,最后是JavaScript,我的代码如下。 C#:
using System;
using System.Collections.Generic;
using System.Linq;
public class Kata
{
public static IEnumerable<string> OpenOrSenior(int[][] data) => data.Select(x => { return (x[0] >= 55 && x[1] > 7) ? "Senior" : "Open"; });
}
的Python:
def openOrSenior(array): return [ "Senior" if (x[0] >= 55 and x[1] > 7) else "Open" for x in array]
JavaScript的:
function openOrSenior(data) { return data.map(x => { if(x[0] >= 55 && x[1] > 7){return "Senior";}else{return "Open";} }); }
我在F#解决这个问题时遇到了麻烦...... 我是F#的新手,我已经写出了Fuchu测试。 如果可能的话,我需要对我应该对我的F#代码进行的一些更改提供一些帮助。 F#: 函数参数需要采用2D数组。
let OpenOrSenior _ =
let mutable _list : List<string> = []
let mutable _val : string = ""
for i in _ do
_val <- if i.[0] >= 55 && i.[1] > 7 then "Senior" else "Open"
_list <- _val :: _list
请让我知道你的想法。 提前谢谢。
答案 0 :(得分:2)
我调整了你的可变版本以使其正常工作。最后一行反转列表以使订单正确:
let openOrSenior (input:int list list) =
let mutable _list : List<string> = []
let mutable _val : string = ""
for i in input do
_val <- if i.[0] >= 55 && i.[1] > 7 then "Senior" else "Open"
_list <- _val :: _list
_list |> List.rev
然而,使用mutable关键字是代码味道的标志。这是一个功能更强大的版本:
let openOrSenior =
List.map
(function
|age::[hcp] when age >= 55 && hcp > 7 -> "Senior"
|_ -> "Open")
注意:你需要更换,用;在你的输入中。逗号用于F#中的元组。
答案 1 :(得分:2)
正如评论fsharpforfunandprofit所建议的那样,F# wiki和MS docs都很棒。对于更多开放式问题,只需按F# Slack。
有几点,首先,通过元组列表或记录,然后通过列表列表,可以更好地建模域。 Open或Senior也应由被歧视的联盟建模。这样你就可以匹配大多数惯用和类型安全的代码。但是,您可以简单地重写函数以获取列表列表,并在其上映射函数,就像在其他示例中一样:
let ageAndHandi = [[18; 20];[45; 2];[61; 12];[37; 6];[21; 21];[78; 9]]
let openOrSenior (xs:List<List<int>>) =
xs
|> List.map
(fun (x:List<int>) -> if x.[0] >= 55 && x.[1] > 7 then "Senior" else "Open")
openOrSenior ageAndHandi //val it : string list = ["Open"; "Open"; "Senior"; "Open"; "Open"; "Senior"]
有两种方法可以在F#中指定类型,.NET(List<List<int>>
)和ML int list list
。无论哪种方式都没关系。然而,首选方法是避免类型注释,让类型推断发挥其神奇作用,并使代码尽可能通用。因此,您根本不需要对列表进行注释。
正如我所说,你也可以通过理解来做到这一点,即使你不了解F#也应该是非常易读的:
let openOrSenior2 xs =
[for (x:List<int>) in xs do
if x.[0] >= 55 && x.[1] > 7 then yield "Senior" else yield "Open"]
openOrSenior2 ageAndHandi
这是实际建模域的版本,并使用模式匹配:
//record to describe a club member
type ClubMember = {
age: int
handi: int
}
//Discriminated Union to describe possible sub-types of club member
type MemberType = Open | Senior
//list of club members
let ageAndHandi2 = [{age=18;handi=20}
{age=45;handi=2}
{age=61;handi=12}]
//function to return the type of club member, notice that it's not a string
//but you could do that as well
let selectMember (mem:ClubMember) =
match mem with
| x when (mem.age >= 55) && (mem.handi > 7) -> Senior
| _ -> Open
//pipe the member list into the selection function, which return a MemberType List
ageAndHandi2
|> List.map selectMember
//val it : MemberType list = [Open; Open; Senior]
答案 2 :(得分:1)
" 对新成员进行分类 "
JavaSvcript 使用映射和三元运算符的代码。
function openOrSenior(data){
return data.map( x => x[0] >= 55 && x[1] > 7 ? "Senior" : "Open");
}
console.log(openOrSenior([[45, 12],[55,21],[19, -2],[104, 20]])); //,['Open', 'Senior', 'Open', 'Senior'])
console.log(openOrSenior([[3, 12],[55,1],[91, -2],[54, 23]])); //,['Open', 'Open', 'Open', 'Open'])
console.log(openOrSenior([[59, 12],[55,-1],[12, -2],[12, 12]])); //,['Senior', 'Open', 'Open', 'Open'])
答案 3 :(得分:0)
function openOrSenior(data){
return data.map(dig => (dig[0] >= 55 && dig[1] > 7 ? 'Senior' : 'Open'));
}