Implement isSorted,它检查Array [A]是否根据给定的比较函数进行排序:
def isSorted [A](例如:Array [A],顺序:(A,A)=>布尔值):布尔值
这是我的实现方式
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/auth";
//https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.cookiebuilder?view=aspnetcore-2.1
options.Cookie = new CookieBuilder
{
Name = "CustomCookie",
HttpOnly = false
};
});
}
public async void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
}
我遇到了这个异常:
@tailrec
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if(as.length==0 || as.length == 1 || as.isEmpty) true
else if(!ordered(as(0),as(1))) false
isSorted(as.tail,ordered)
}
我不太了解,当java.lang.UnsupportedOperationException: empty.tail
为空时,它应该返回true。
答案 0 :(得分:4)
在Scala中,在方法或块内求值的最后一个表达式成为该方法或块的值。
在您的情况下,在方法内部求值的最后一个表达式是:
isSorted(as.tail,ordered)
因此,这是返回值。 总是。
在该表达式之前,您的方法中还有另一个表达式:
if(as.length==0 || as.length == 1 || as.isEmpty) true
else if(!ordered(as(0),as(1))) false
但是:
因此,此表达式本质上是无操作的,而您的方法实际上就是这样:
@tailrec
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean =
isSorted(as.tail,ordered)
您的方法将简单地递归直到数组为空,然后抛出异常,因为您尝试使用空数组的尾部再次递归。
最简单的解决方法是使最后一个表达式成为较大表达式的一部分,以便您的方法仅包含一个表达式:
@tailrec
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if(as.length==0 || as.length == 1 || as.isEmpty) true
else if(!ordered(as(0),as(1))) false
else isSorted(as.tail,ordered)
//↑↑↑↑ This is the only change needed.
}
现在,让我们进行一次小型游览:Scala风格!
您的空白样式不一致。有时,运算符周围会有空格,有时却没有,并且不清楚何时选择一个或另一个,其含义是什么。例如,在这里:
if(as.length==0 || as.length == 1 || as.isEmpty) true
// ↑↑ ↑↑↑↑ ↑↑↑↑ ↑↑↑↑
您使用什么标准来决定何时使用空白?您在||
和第二个==
而不是第一个if(as.length == 0 || as.length == 1 || as.isEmpty) true
// ↑↑↑↑ ↑↑↑↑ ↑↑↑↑ ↑↑↑↑
周围使用空格是什么意思?您希望通过该决定告诉我什么,代码的读者吗?
我个人会这样写:
else if(!ordered(as(0), as(1))) false
// ↑
else isSorted(as.tail, ordered)
// ↑
这也与标准《 Scala社区风格指南》保持一致。
同样,您在参数列表中的逗号后使用空格,而在参数列表中不使用空格。标准的《 Scala社区样式指南》建议在逗号后使用空格以提高可读性:
if
标准的《 Scala社区风格指南》还建议在控制流关键字(例如while
或if (as.length == 0 || as.length == 1 || as.isEmpty) true
//↑
else if (!ordered(as(0), as(1))) false
// ↑
之后使用空格,以将它们与方法调用区分开来:
if (as.length == 1 || as.isEmpty) true
此外,请注意,检查零长度和空度是多余的,它们是同一回事:
@tailrec
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean =
if (as.length == 1 || as.isEmpty) true
else if (!ordered(as(0), as(1))) false
else isSorted(as.tail, ordered)
最后,既然我们的方法只包含一个表达式,我们就不再需要花括号了。
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean) =
as.sliding(2).forall { case Array(a, b) => ordered(a, b) }
但是,实际上有一种更好的方法可以解决此问题:如果对每个连续的元素对都进行排序,则对数组进行排序:
A
您的方法签名不方便。类型推断只会从一个参数列表流到下一个参数列表,而不会在一个参数列表内,因此在您的情况下,编译器将不知道ordered
中的A
是什么,即使它已经知道了什么。 as
在isSorted(Array(1, 5, 3, 4), (a, b) => a < b)
// error: missing parameter type
// isSorted(Array(1, 5, 3, 4), (a, b) => a < b)
// ^
// error: missing parameter type
// isSorted(Array(1, 5, 3, 4), (a, b) => a < b)
// ^
中:
isSorted(Array(1, 5, 3, 4), (a: Int, b: Int) => a < b)
//=> res: Boolean = false
您必须明确告诉编译器类型:
def isSorted[A](as: Array[A])(ordered: (A, A) => Boolean) =
as.sliding(2).forall { case Array(a, b) => ordered(a, b) }
因此,最好将功能参数放在单独的参数列表中:
isSorted(Array(1, 5, 3, 4))((a, b) => a < b)
//=> res: Boolean = false
现在,类型推断可以按预期工作:
isSorted(Array(1, 5, 3, 4)) { _ < _ }
//=> res: Boolean = false
您还可以使用占位符阻止函数的语法:
as
最后,签名实际上受到了不必要的限制:实际上并没有要求Array
成为Seq
,它对于更通用的类型(例如{{1})也同样适用}:
def isSorted[A](as: Seq[A])(ordered: (A, A) => Boolean) =
as.sliding(2).forall { case Seq(a, b) => ordered(a, b) }
现在,例如,我们也可以传递List
而不是仅传递Array
。实际上,只需重写一下该方法,就应该有可能使它适用于 all Iterable
s。
答案 1 :(得分:0)
使用返回关键字:
@tailrec
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if (as.length == 0 || as.length == 1 || as.isEmpty) return true
else if (!ordered(as(0), as(1))) return false
isSorted(as.tail, ordered)
}
或者您可以执行此操作(建议):
@tailrec
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if (as.length == 0 || as.length == 1 || as.isEmpty) return true
else if (!ordered(as(0), as(1))) return false
else isSorted(as.tail, ordered)
}