Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
根据Scala中的不止一个约束对列表进行排序_Scala_Sorting_Scala Collections - Fatal编程技术网

根据Scala中的不止一个约束对列表进行排序

根据Scala中的不止一个约束对列表进行排序,scala,sorting,scala-collections,Scala,Sorting,Scala Collections,我正在拼命寻找一种对字符串列表排序的方法,其中字符串是以下形式的预定义标识符:a1.1、a1.2、…、a1.100、a2.1、a2.2、…、a2.100、…、b1.1、b1.2、,。。以此类推,这是正确的顺序。因此,每个标识符首先按其第一个字符的字母顺序降序排列,并在此顺序内按连续数字降序排列。我尝试过sortWith,它提供了一个排序函数,为所有两个连续的列表成员指定上述规则 scala> List("a1.102", "b2.2", "b2.1", "a1.1").sortWith((

我正在拼命寻找一种对字符串列表排序的方法,其中字符串是以下形式的预定义标识符:a1.1、a1.2、…、a1.100、a2.1、a2.2、…、a2.100、…、b1.1、b1.2、,。。以此类推,这是正确的顺序。因此,每个标识符首先按其第一个字符的字母顺序降序排列,并在此顺序内按连续数字降序排列。我尝试过sortWith,它提供了一个排序函数,为所有两个连续的列表成员指定上述规则

scala> List("a1.102", "b2.2", "b2.1", "a1.1").sortWith((a: String, b: String) => a.take(1) < b.take(1) && a.drop(1).toDouble < b.drop(1).toDouble)
res2: List[java.lang.String] = List(a1.102, a1.1, b2.2, b2.1)
这不是我期望的订货。但是,通过交换表达式的顺序

scala> List("a1.102", "b2.2", "b2.1", "a1.1").sortWith((a: String, b: String) => (a.drop(1).toDouble < b.drop(1).toDouble && a.take(1) < b.take(2)))
res3: List[java.lang.String] = List(a1.1, a1.102, b2.1, b2.2)
这确实给了我至少这个示例所需的顺序,我也不理解

如果有人能给我一个提示,告诉我这里到底发生了什么,以及我如何用一个比只比较<或>更复杂的布尔表达式对列表进行排序,我将不胜感激。还有一个问题:我在示例中排序的字符串实际上是HashMap m中的键。任何解决方案是否会影响按其键对m进行排序

m.toSeq.sortWith((a: (String, String), b: (String, String)) => a._1.drop(1).toDouble < b._1.drop(1).toDouble && a._1.take(1) < b._1.take(1))

提前感谢

更新:我误读了您的示例,您希望a1.2先于a1.102,而下面的toDouble版本不会正确。我的建议是:

items.sortBy { s =>
  val Array(x, y) = s.tail.split('.')
  (s.head, x.toInt, y.toInt)
}
这里我们将Scala的排序实例用于Tuple3[Char,Int,Int]

看起来您的第二个正确版本中有一个输入错误:b.take2应该没有意义,应该是b.take1以匹配第一个。一旦你解决了这个问题,你就会得到同样错误的订单

真正的问题是,在数字匹配的情况下,只需要第二个条件。因此,以下工作符合要求:

val items = List("a1.102", "b2.2", "b2.1", "a1.1")
items.sortWith((a, b) =>
  a.head < b.head || (a.head == b.head && a.tail.toDouble < b.tail.toDouble)
)
在这里,我们利用Scala为Tuple2[Char,Double]提供了一个适当的排序实例这一事实,因此我们可以提供一个转换函数,将您的项转换为该类型


回答你的最后一个问题:是的,这两种方法中的任何一种都应该适用于你的地图示例。

更新:我误读了你的示例,你希望a1.2先于a1.102,而下面的toDouble版本不会正确。我的建议是:

items.sortBy { s =>
  val Array(x, y) = s.tail.split('.')
  (s.head, x.toInt, y.toInt)
}
这里我们将Scala的排序实例用于Tuple3[Char,Int,Int]

看起来您的第二个正确版本中有一个输入错误:b.take2应该没有意义,应该是b.take1以匹配第一个。一旦你解决了这个问题,你就会得到同样错误的订单

真正的问题是,在数字匹配的情况下,只需要第二个条件。因此,以下工作符合要求:

val items = List("a1.102", "b2.2", "b2.1", "a1.1")
items.sortWith((a, b) =>
  a.head < b.head || (a.head == b.head && a.tail.toDouble < b.tail.toDouble)
)
在这里,我们利用Scala为Tuple2[Char,Double]提供了一个适当的排序实例这一事实,因此我们可以提供一个转换函数,将您的项转换为该类型


并回答您的最后一个问题:是的,这些方法中的任何一种都应该与您的地图示例一致。

因此,考虑当您的排序函数通过A= A1.1和B= A1.102时会发生什么。 您希望函数返回true。但是,a.take1 仔细想想你的案子

如果前缀相等,并且尾部的顺序正确,则参数的顺序正确 如果前缀不相等,则仅当前缀相等时,参数的顺序才正确。 因此,请尝试以下方法:

(a: String, b: String) => if (a.take(1) == b.take(1)) a.drop(1).toDouble < b.drop(1).toDouble else a.take(1) < b.take(1)

反向函数首先对字符串的数字部分进行排序,然后对前缀进行排序。恰巧,您所给出的数字排序也保留了前缀排序,但情况并非总是如此。

因此,考虑当您的排序函数通过A= A1.1和B= A1.102时会发生什么。 您希望函数返回true。但是,a.take1 仔细想想你的案子

如果前缀相等,并且尾部的顺序正确,则参数的顺序正确 如果前缀不相等,则仅当前缀相等时,参数的顺序才正确。 因此,请尝试以下方法:

(a: String, b: String) => if (a.take(1) == b.take(1)) a.drop(1).toDouble < b.drop(1).toDouble else a.take(1) < b.take(1)

反向函数首先对字符串的数字部分进行排序,然后对前缀进行排序。碰巧,您给出的数字顺序也保留了前缀顺序,但情况并非总是如此。

创建一个元组,其中包含前缀前的字符串。然后是..后面的整数。。第一部分使用字典顺序,第二部分使用整数顺序

scala> val order = Ordering.by((s:String) => (s.split("\\.")(0),s.split("\\.")(1).toInt))
order: scala.math.Ordering[String] = scala.math.Ordering$$anon$7@384eb259

scala> res2
res8: List[java.lang.String] = List(a1.5, a2.2, b1.11, b1.8, a1.10)


scala> res2.sorted(order)
res7: List[java.lang.String] = List(a1.5, a1.10, a2.2, b1.8, b1.11)

创建一个元组,该元组包含。然后是..后面的整数。。第一部分使用字典顺序,第二部分使用整数顺序

scala> val order = Ordering.by((s:String) => (s.split("\\.")(0),s.split("\\.")(1).toInt))
order: scala.math.Ordering[String] = scala.math.Ordering$$anon$7@384eb259

scala> res2
res8: List[java.lang.String] = List(a1.5, a2.2, b1.11, b1.8, a1.10)


scala> res2.sorted(order)
res7: List[java.lang.String] = List(a1.5, a1.10, a2.2, b1.8, b1.11)

非常感谢大家!我是Scala编程新手,但我非常喜欢它!但我仍然会遇到一些严重的头痛,像这样的事情;我想,我会得到一份清单,比如
其中每两个连续元素都与我的约束匹配。我已经接受了第二个答案,因为我现在一切都清楚了。因为每一个答案都确实帮助我学到了更多,但我是这个委员会的新成员,请让我知道,如果需要的话,我如何能够给予这些有用的答案!谢谢大家的友谊女:干杯!非常感谢大家!我是Scala编程新手,但我非常喜欢它!但我仍然会遇到一些严重的头痛,像这样的事情;我假设,我会得到一个列表,其中每两个连续元素都与我的约束匹配。我已经接受了第二个答案,因为我现在一切都清楚了。因为每一个答案都确实帮助我学到了更多,但我是这个委员会的新成员,请让我知道,如果需要的话,我如何能够给予这些有用的答案!谢谢大家的友谊女:干杯!如果前缀只升到a2是可以的,但如果它升到a10或更高,字典顺序将停止工作,因此像特拉维斯那样做可能更安全如果前缀只升到a2是可以的,但是如果它升到a10或更高,字典顺序将停止工作,所以像特拉维斯那样做可能更安全