Scala的集合有三大类:
序列Seq、集Set、映射Map
所有的集合都扩展自Iterable特质。对于几乎所有的集合类
Scala都同时提供了可变和不可变的版本
可变集合
可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。
不可变集合
永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。
但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变,
所以这里的不可变并不是变量本身的值不可变,而是变量指向的那个内存地址不可变
集合特质
-- scala.collection.immutable

-- scala.collection.mutable

严格意义上,数组不是集合
scala中给数组一个特定的类型:Array
构建Scala中的数组,其实等同于构造Java的数组
基本语法
数组定义
// 集合分为两大类:可变集合,不可变集合
// Scala默认提供的集合都是不可变。
// val array = new Array[String](3)
// array(0) = "a"
// array(1) = "a"
// array(2) = "a"
// 使用集合的伴生对象构建集合,并同时初始化
val array1 = Array(1,2,3,4)
val array2 = Array(5,6,7,8)
//val array2 = Array.apply(1,2,3,4)
数组赋值
修改某个元素的值
arr01(3) = 10
val i = 10
arr01(i/3) = 20
采用方法的形式修改数组的值
arr01.update(0,1)
遍历数组
查看数组
println(arr01.mkString(","))
普通遍历
for (i <- arr01) {
println(i)
}
简化遍历
def printx(elem:Int): Unit = {
println(elem)
}
arr01.foreach(printx)
arr01.foreach((x)=>{println(x)})
arr01.foreach(println(_))
arr01.foreach(println)
基本操作
val arr1 = Array(1,2,3,4)
val arr3: Array[Int] = arr1 :+ 5
println( arr1 eq arr3 ) // false
arr3.foreach(println)
// 12345
val arr1 = Array(1,2,3,4)
val arr2 = Array(5,6,7,8)
val arr5: Array[Int] = arr1 ++ arr2
arr5.foreach(println)
// 12345678
var myMatrix = Array.ofDim[Int](3,3)
myMatrix.foreach(list=>println(list.mkString(",")))
// 0,0,0
// 0,0,0
// 0,0,0
val arr1 = Array(1,2,3,4)
val arr2 = Array(5,6,7,8)
// 合并数组
val arr6: Array[Int] = Array.concat(arr1, arr2)
arr6.foreach(println)
// 12345678
// 创建指定范围的数组
val arr7: Array[Int] = Array.range(0,2)
arr7.foreach(println)
// 01
val arr8:Array[Int] = Array.fill[Int](5)(-1)
arr8.foreach(println)
基本语法
val buffer = new ArrayBuffer[String]()
val buffer = ArrayBuffer("a", "b", "c")
println(buffer)
// ArrayBuffer(a, b, c)
buffer.append("a", "b", "c", "d")
// ArrayBuffer(a, b, c, a, b, c, d)
buffer.appendAll(Array("a", "b", "c"))
// ArrayBuffer(a, b, c, a, b, c, d, a, b, c)
val buffer1 = ArrayBuffer(1,2,3,4)
val buffer2 = ArrayBuffer(5,6,7,8)
val buffer3: ArrayBuffer[Int] = buffer1 += 5
println( buffer1 eq buffer3 ) // true
// 使用 ++ 运算符会产生新的集合数组
val buffer4: ArrayBuffer[Int] = buffer1 ++ buffer2
// 使用 ++= 运算符会更新之前的集合,不会产生新的数组
val buffer5: ArrayBuffer[Int] = buffer1 ++= buffer2
println( buffer1 eq buffer4 ) // false
println( buffer1 eq buffer5 ) // true
buffer.update(0, "e")
buffer(0) = "e"
val buffer = ArrayBuffer("a", "b", "c")
buffer.remove(2) // ArrayBuffer(a, b)
val buffer = ArrayBuffer("a","b","c","a","b","c","d")
buffer.remove(2,2) // ArrayBuffer(a, b, b, c, d)
val strings: ArrayBuffer[String] = buffer - "a"
println(buffer eq strings)
println(buffer)
println(strings)
// false
// ArrayBuffer(a, b, c)
// ArrayBuffer(b, c)
println(buffer(3))
for ( i <- buffer ) {
println(i)
}
val buffer = ArrayBuffer(1,2,3,4)
val array = Array(4,5,6,7)
// 将不可变数组转换为可变数组
val buffer1: mutable.Buffer[Int] = array.toBuffer
// 将可变数组转换为不可变数组
val array1: Array[Int] = buffer.toArray
val array = Array(1,2,3,4)
println(array.size) // 4
println(array.length) // 4
println(array.isEmpty) // false
println(array.contains(2)) // true 判断集合中是否包含某个元素
println(array.distinct.mkString(",")) // 1,2,3,4
println(array.reverse.mkString(",")) // 4,3,2,1
println(array.mkString(",")) // 1,2,3,4
array.foreach(println)
// 1
// 2
// 3
// 4
val iterator = array.iterator // 生成迭代器
while (iterator.hasNext){
println(iterator.next())
}
// 1
// 2
// 3
// 4
val array = ArrayBuffer(1,2,3,4)
// 从集合中获取部分数据
println(array.head) // 1
println(array.tail) // ArrayBuffer(2, 3, 4)
println(array.tails) // <iterator>
println(array.last) // 4
println(array.init) // 初始 ArrayBuffer(1, 2, 3) 返回当前序列中不包含最后一个元素的序列(去尾)
println(array.inits) // <iterator> 对集合中的元素进行 init 操作,该操作的返回值中, 第一个值是当前序列的副本,包含当前序列所有的元素,最后一个值是空的,对头尾之间的值进行init操作,上一步的结果作为下一步的操作对象
// 取前几个
println(array.take(3)) // ArrayBuffer(1, 2, 3)
println(array.reverse.take(2).reverse) // ArrayBuffer(3, 4)
println(array.takeRight(2)) // ArrayBuffer(3, 4)
println(array.drop(1)) // ArrayBuffer(2, 3, 4)
println(array.dropRight(1)) // ArrayBuffer(1, 2, 3)
val array = ArrayBuffer(1,2,3,4,5)
println(array.sum) // 15 加法
println(array.max) // 5
println(array.min) // 1
println(array.product) // 120 乘法
// 自定义数据操作的方法
// 集合的数据无论是多少,最基本的数据操作其实都是两两计算。
// map => reduce => 简化,规约(聚合)
def reduceFunction(x : Int, y : Int): Int = {
x + y
}
//println(array.reduce(reduceFunction))
//println(array.reduce((x:Int, y:Int)=>{x + y}))
//println(array.reduce((x:Int, y:Int)=>x + y))
//println(array.reduce((x, y)=>x + y))
println(array.reduce(_ - _)) // -13
// reversed.reduceLeft[B]((x, y) => op(y, x))
// 【1,2,3,4, 5】
// 【5,4,3,2,1】
// 1 - (2 - (3 - (4 - 5)))
println(array.reduceRight(_ - _)) // 3
1 - ( 2 - ( 3 - ( 4 - 5 ) ) )
println(array.reduceLeft(_ - _)) // -13
( ( ( 1 - 2 ) - 3 ) - 4 ) - 5
val array = ArrayBuffer(1,2,3,4)
val num = 5
// 折叠
println(array.fold(5)(_ - _)) // -5
// (((5 - 1) - 2) - 3) - 4
println(array.foldLeft(5)(_ - _)) // -5
// reversed.foldLeft(z)((x, y) => op(y, x))
// 【1,2,3,4】
// 【4,3,2,1】
// 1 - (2 - (3 - (4 - 5)))
println(array.foldRight(5)(_ - _)) // 3
println(array.scan(5)(_ - _)) // ArrayBuffer(5, 4, 2, -1, -5)
println(array.scanLeft(5)(_-_)) // ArrayBuffer(5, 4, 2, -1, -5)
println(array.scanRight(5)(_-_)) // ArrayBuffer(3, -2, 4, -1, 5)
val array = ArrayBuffer(1,2,3,4)
// TODO 功能函数:由集合对象提供函数执行自定义的功能
// 1. map => 映射(转换) => K->V
// a => b
// map方法需要传递一个参数,这个参数的类型为函数类型: Int => B
def mapFunction( num:Int ): Int = {
num * 2
}
println(array.map(mapFunction)) // ArrayBuffer(2, 4, 6, 8)
println(array.map(
(num:Int) => {
num * 2
}
)) // ArrayBuffer(2, 4, 6, 8)
println(array.map(_*2)) // ArrayBuffer(2, 4, 6, 8)
val array = ArrayBuffer(
ArrayBuffer(
ArrayBuffer(1,2),ArrayBuffer(5,6)
), ArrayBuffer(
ArrayBuffer(3,4),ArrayBuffer(7,8)
)
)
println(array.flatten.flatten)
// ArrayBuffer(1, 2, 5, 6, 3, 4, 7, 8)
val array = Array(
"Hello Scala", "Hello Hadoop"
)
println(array.flatten.mkString(","))
// H,e,l,l,o, ,S,c,a,l,a,H,e,l,l,o, ,H,a,d,o,o,p
println(array.flatMap(
str => {
str.split(" ")
}
).mkString(","))
// Hello,Scala,Hello,Hadoop
filter方法可以对集合中的每一条数据进行筛选过滤
满足条件(true)的数据保留,不满足条件(false)的数据丢弃
val array = ArrayBuffer(1,2,3,4)
val r = array.filter(
num => {
num % 2 != 0
}
)
println(r) // ArrayBuffer(1, 3)
根据指定的规则对每一条数据进行分组
val array = ArrayBuffer(1,2,3,4)
// 根据指定的规则对每一条数据进行分组
val r = array.groupBy(
num => {
if ( num % 2 == 0 ) {
"偶数"
} else {
"奇数"
}
num % 2
}
)
println(r) // Map(1 -> ArrayBuffer(1, 3), 0 -> ArrayBuffer(2, 4))
val array2 = ArrayBuffer(
"Hello", "Scala", "Hadoop", "Spark"
)
println(array2.groupBy(_.substring(0, 1)))
// Map(S -> ArrayBuffer(Scala, Spark), H -> ArrayBuffer(Hello, Hadoop))
排序:通过指定的规则对每一条数据进行排序处理, 默认为升序
val array = ArrayBuffer("1", "11", "2", "3", "22")
println(array.sortBy(
num => num.toInt
)) // ArrayBuffer(1, 2, 3, 11, 22)
println(array.sortBy(num => num.toInt)(Ordering.Int.reverse)) // ArrayBuffer(22, 11, 3, 2, 1)
// TODO 1. 读取文件,获取原始数据
// line => Hello Scala
val source: BufferedSource = Source.fromFile("data/word.txt")
val lines: Array[String] = source.getLines().toArray
source.close()
// TODO 2. 将原始数据进行切分成一个一个的单词
// "Hello Scala" => "Hello", "Scala"
val words = lines.flatMap(
line => {
line.split(" ")
}
)
// TODO 3. 对分词的结果进行分组操作(相同的单词放置在一起)
// "Hello", "Hello" => { "Hello"=>List( Hello, Hello ) }
val wordGroup: Map[String, Array[String]] = words.groupBy(word => word)
// TODO 4. 对分组后的数据进行数量的统计
// 如果数据在转换时,无需对key进行操作,只对v进行处理时,可以使用mapValues方法
// { "Hello"=>List( Hello, Hello ) }
// =>
// { "Hello"=>2 }
val wordCount = wordGroup.mapValues(
v => {
v.size
}
)
// fun2
// val wordCount = wordGroup.map {
// case (word, list) => {
// (word, list.size)
// }
// }
// TODO 5. 将统计结果打印在控制台
println(wordCount)
简化代码
val source: BufferedSource = Source.fromFile("data/word.txt")
val lines: Array[String] = source.getLines().toArray
source.close()
val wordCount =
lines
.flatMap(_.split(" "))
.groupBy(word => word)
.mapValues(_.size)
println(wordCount)
合并count01
val list = List(
("Hello Scala", 4),
("Hello World", 2)
)
val list2 = list.map(
t => {
val line = t._1
val cnt = t._2
(line + " ") * cnt // 连词
}
)
println(list2)
// List(Hello Scala Hello Scala Hello Scala Hello Scala , Hello World Hello World )
合并count02
val list = List(
("Hello Scala", 4),
("Hello World", 2)
)
// ("Hello Scala", 4) => ("Hello", 4),("Scala", 4)
// ("Hello World", 2) => ("Hello", 2),("World", 2)
val list1 = list.flatMap(
t => {
val line = t._1
val cnt = t._2
val datas = line.split(" ") // Hello,Scala => (Hello, 4), (Scala, 4)
datas.map(
word => {
(word, cnt)
}
)
}
)
val groupData: Map[String, List[(String, Int)]] = list1.groupBy(_._1)
/*
Map(
Hello -> List((Hello,4), (Hello,2)),
Scala -> List((Scala,4)),
World -> List((World,2)))
Map(
Hello -> List(4, 2),
Scala -> List(4),
World -> List(2))
Map(
Hello -> 6,
Scala -> 4,
World -> 2
*/
val groupData1 = groupData.mapValues(
list => {
list.map(_._2).sum
}
)
println(groupData1)
基本语法
声明
// 一般会从采用List
val seq = Seq(1,2,3,4)
val list = List(1,2,3,4)
val list1 = List(5,6,7,8)
数据操作
val ints: List[Int] = list :+ 5
println(list eq ints) // false
val ints1: List[Int] = 5 +: list
println(list) // List(1, 2, 3, 4)
println(ints) // List(1, 2, 3, 4, 5)
println(ints1) // List(5, 1, 2, 3, 4)
Nil 在集合中表示空集合
val ints2 = 1 :: 2:: 3 :: Nil
//Nil.::(3).::(2).::(1)
val ints3 = 1 :: 2 :: 3 :: list1 ::: Nil
println(Nil) // List()
println(ints2) // List(1, 2, 3)
println(ints3) // List(1, 2, 3, 5, 6, 7, 8)
数据有序,可以放重复数据
val list = List(1,3,4,2,1)
println(list) // List(1, 3, 4, 2, 1)
方法
插入
val list = ListBuffer(1,3,4,2,1)
val list2 = ListBuffer(1,3,4,2,1)
list.append(1)
println(list)
list.appendAll(list2)
println(list)
list.insert(0,10)
println(list)
// ListBuffer(1, 3, 4, 2, 1, 1)
// ListBuffer(1, 3, 4, 2, 1, 1, 1, 3, 4, 2, 1)
// ListBuffer(10, 1, 3, 4, 2, 1, 1, 1, 3, 4, 2, 1)
更新
val list = ListBuffer(1,3,4,2,1)
list.update(0, 5) // 改变自身
println(list)
list.updated(0, 6) // 创建新的
println(list)
println(list.updated(0, 6))
// ListBuffer(5, 3, 4, 2, 1)
// ListBuffer(5, 3, 4, 2, 1)
// ListBuffer(6, 3, 4, 2, 1)
删除
val list = ListBuffer(1,3,4,2,1)
list.remove(1)
println(list)
list.remove(1,2)
println(list)
// ListBuffer(1, 4, 2, 1)
// ListBuffer(1, 1)
遍历
val list = ListBuffer(1,3,4,2,1)
println(list.mkString(","))
val iterator = list.iterator
while (iterator.hasNext) {
println(iterator.next())
}
list.foreach(println)
// 1,3,4,2,1
// 1
// 3
// 4
// 2
// 1
// 1
// 3
// 4
// 2
// 1
类型转换
val list = ListBuffer(1,3,4,2,1)
val list1 = list.toList
val list2 = list1.toBuffer
数据无序,不可重复
// update方法用于更新set集合
set.update(5, true)
println(set)
set.update(4, false)
println(set)
set.remove(3)
// Set(1, 5, 2, 3, 4)
// Set(1, 5, 2, 3)
// Set(1, 5, 2)
set.foreach(println) //遍历数据
交集与差集
val set1 = mutable.Set(1,2,3,4)
val set2 = mutable.Set(4,5,6,7)
// 交集
val set3: mutable.Set[Int] = set1 & set2
println(set3.mkString(",")) // 4
// 差集
val set4: mutable.Set[Int] = set1 &~ set2
println(set4.mkString(",")) // 1,2,3
Map(映射)是一种可迭代的键值对(key/value)结构。所有的值都可以通过键来获取。Map 中的键都是唯一的。
数据无序,K不能重复的集合
不可变Map
val map = Map(
"a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5
)
val map1 = mutable.Map(
"a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5
) // K不能重复的集合
map1.put("f", 6)
println(map1) // Map(e -> 5, b -> 2, d -> 4, a -> 3, f -> 6)
map1.update("a", 7)
println(map1) // Map(e -> 5, b -> 2, d -> 4, a -> 7, f -> 6)
map1.remove("e")
println(map1) // Map(b -> 2, d -> 4, a -> 7, f -> 6)
// java中从HashMap中获取一个不存在的key,会返回null
// HashMap允许放空键(Key)空值(Value)
val map1 = mutable.Map(
"a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5
)
val maybeInt1: Option[Int] = map1.get("f")
// Option类型专门为了解决空指针问题设计的
// Option : 选项,对象只有2个 Some, None
if ( maybeInt1.isEmpty ) {
println("没有对应key的值, 提供默认值 : " + maybeInt1.getOrElse(0))
} else {
println("对应key的值为" + maybeInt1.get)
}// print --> 没有对应key的值, 提供默认值 : 0
println("获取指定key的值:" + maybeInt1.getOrElse(0)) // print--> 获取指定key的值:0
// 如果不存在,获取默认值
println(map1.getOrElse("a", 0)) // 3
//获取可能存在的key值, 如果不存在就使用默认值
可以将无关的元素组合在一起,形成一个整体来进行访问,这种整体结构称之元素组合
因为元组中的数据没有关系,所以只能通过顺序号进行访问
val t : (Int, String, Int) = (1, "zhangsan", 30)
println(t._1) // 1
println(t._2) // zhangsan
println(t._3) // 30
// Tuple也是一个集合对象,所以也有类型
// (Int, String, Int)
// scala中元组也有专门的类型
val t1 : Tuple3[Int, String, Int] = (1, "zhangsan", 30)
// Tuple类型最多存放元素的数量为22个。但是类型没有约束的。
println(t) // (1,zhangsan,30)
如果元组中的元素只有2个,称之为对偶元组,也可以称之为键值对
val kv = (1, "zhangsan")
val map = Map(
("a", 1), ("b", 2), ("c", 3)
)
map.foreach(
t => {
println(t._1 + "=" + t._2)
}
)
println(map)
// a=1
// b=2
// c=3
// Map(a -> 1, b -> 2, c -> 3)
将Map转换为List
val list: List[(String, Int)] = map.toList
// 不同省份的商品点击排行
// word(省份-商品) - count(1)
val datas = List(
("zhangsan", "河北", "鞋"),
("lisi", "河北", "衣服"),
("wangwu", "河北", "鞋"),
("zhangsan", "河南", "鞋"),
("lisi", "河南", "衣服"),
("wangwu", "河南", "鞋"),
("zhangsan", "河南", "鞋"),
("lisi", "河北", "衣服"),
("wangwu", "河北", "鞋"),
("zhangsan", "河北", "鞋"),
("lisi", "河北", "衣服"),
("wangwu", "河北", "帽子"),
("zhangsan", "河南", "鞋"),
("lisi", "河南", "衣服"),
("wangwu", "河南", "帽子"),
("zhangsan", "河南", "鞋"),
("lisi", "河北", "衣服"),
("wangwu", "河北", "帽子"),
("lisi", "河北", "衣服"),
("wangwu", "河北", "电脑"),
("zhangsan", "河南", "鞋"),
("lisi", "河南", "衣服"),
("wangwu", "河南", "电脑"),
("zhangsan", "河南", "电脑"),
("lisi", "河北", "衣服"),
("wangwu", "河北", "帽子")
)
// TODO 将原始数据进行结构的转换
// (人,省份,商品) => (省份-商品, 1)
val mapDatas = datas.map(
t => {
(t._2 + "-" + t._3, 1)
}
)
// TODO 将转换结构后的数据进行分组
val groupDatas: Map[String, List[(String, Int)]] = mapDatas.groupBy(_._1)
// TODO 将分组后的数据进行统计聚合
val cntDatas = groupDatas.mapValues(
list => list.size
)
//println(cntDatas)
// TODO 将聚合的结果进行结构的转换
// 将相同省份的数据准备放在一起
// (省份-商品, count) => (省份,(商品,count))
val mapDatas1 = cntDatas.toList.map(
kv => {
val k = kv._1
val cnt = kv._2
val ks = k.split("-")
(ks(0), (ks(1), cnt))
}
)
// println(mapDatas1)
// 河北 => List( (衣服,20),(鞋,10), )
// TODO 将转换结构后的数据进行排序(降序)
val groupDatas1 =
mapDatas1.groupBy(_._1).mapValues(
list=> {
list.map(_._2).sortBy(_._2)(Ordering.Int.reverse).take(3)
}
)
println(groupDatas1)
// Map(河南 -> List((鞋,6), (衣服,3), (电脑,2)), 河北 -> List((衣服,6), (鞋,4), (帽子,3)))
Scala也提供了队列(Queue)的数据结构,队列的特点就是先进先出。进队和出队的方法分别为enqueue和dequeue。
val que = new mutable.Queue[String]()
// 添加元素
que.enqueue("a", "b", "c")
val que1: mutable.Queue[String] = que += "d"
println(que eq que1) // true
// 获取元素
println(que.dequeue()) // a
println(que.dequeue()) // b
println(que.dequeue()) // c
Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
// val result1 = (0 to 100).map{
// x => {
// Thread.currentThread.getName
// }
// } // main, main, main, main, main, main, main,
val result2 = (0 to 100).par.map{
x => {
Thread.currentThread.getName // 查看线程名字
}
} // scala-execution-context-global-23, scala-execution-context-global-13
println(result1)
println(result2)
快排
val list = List(1,6,5,3,2,4)
val tuple: (List[Int], List[Int]) = list.partition(
num => {
num > 3
}
)
println(tuple._1)
println(tuple._2)
交集,并集,差集
val list1 = List(1,2,3,4)
val list2 = List(3,4,5,6)
// 交集,并集,差集
println(list1.intersect(list2))
println(list1.union(list2))
println(list1.diff(list2))
滑动窗口
val list1 = List(1,2,3,4,5,6,7,8)
//println(list1.drop(1))
//list1.head + list1.tail.head
// 滑动窗口
// 滚动窗口 当窗口大小等于步长是
val iterator: Iterator[List[Int]] = list1.sliding(3, 3) //窗口大小,步长
while (iterator.hasNext) {
val ints: List[Int] = iterator.next()
println(ints)
}
拉链
val list1 = List(1,2,3,4)
val list2 = List(5,6,7,8,9, 10)
// 所谓的拉链,其实就是将两个集合相同的位置的数据连接在一起
val tuples: List[(Int, Int)] = list1.zip(list2)
println(tuples) // List((1,5), (2,6), (3,7), (4,8))
println(list2.zipWithIndex) // 自己和自己的索引拉链
// List((5,0), (6,1), (7,2), (8,3), (9,4), (10,5))
两个map折叠
val map1 = mutable.Map(
("a", 1), ("b", 2), ("c", 3)
)
val map2 = mutable.Map(
("a", 4), ("d", 5), ("c", 6)
)
val map3 = map2.foldLeft(map1)(
(map, kv) => {
val key = kv._1
val cnt = kv._2
val oldCnt = map.getOrElse(key, 0)
map.update(key, oldCnt + cnt)
map
}
)
println(map3) // Map(b -> 2, d -> 5, a -> 5, c -> 9)
使用匿名函数时,给定的参数直接放回,不能使用下划线代替,必须完整,
// val newlist = list3.flatMap(
// list => { // 整体
// list // 容器
// }
// )
val words = list2.flatMap(
str => {
str.split(" ") // 容器( Hello, Scala )
}
)
// 简化规则
def test( f : (String)=>Unit ): Unit = {
f("zhangsan")
}
test( (s:String)=>{println(s)} )
test( (s:String)=>println(s) )
test( (s)=>println(s) )
test( s=>println(s) )
test( s => println(s) )
分组
val list1 = List(1,2,3,4)
val list2 = List("Hello", "Hive", "Hadoop")
val list4 = List(
("a", 1), ("a", 2), ("a", 3)
)
// Map[ 组名1=>分组集合1,组名2=>分组集合2 ]
val list3 = list4.groupBy(
t => t._1
)
println(list3) // Map(a -> List((a,1), (a,2), (a,3)))
val list5 = List(1,4,3,2,5)
// 1 4 3 2 5
// 1 0 1 0 1
// 4 2 1 3 5
// List(4, 2, 1, 3, 5)
//println(list5.sortBy(_ % 2)) // 取余后排序
排序
val user1 = new User()
user1.age = 20
user1.salary = 2000
val user2 = new User()
user2.age = 30
user2.salary = 2000
val user3 = new User()
user3.age = 30
user3.salary = 1000
val users = List(
user1, user2, user3
)
//println(users.sortBy(_.age)(Ordering.Int.reverse))
// Tuple : 元组,可以默认排序,先比较第一个,如果相同,比较第二个,依此类推
// println(
// users.sortBy(
// user => {
// ( user.age, user.salary )
// }
// )(Ordering.Tuple2[Int, Int]( Ordering.Int, Ordering.Int.reverse ))
// )
// 自定义排序
println(users.sortWith(
(user1, user2) => {
// 将你期望的结果,返回为true
//user1.salary > user2.salary
if ( user1.age < user2.age ) {
true
} else if (user1.age == user2.age ) {
user1.salary < user2.salary
} else {
false
}
}
))
}
class User {
var age : Int = _
var salary : Int = _
override def toString: String = {
return s"User[${age}, ${salary}]"
}
}
S
我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排
我有以下python函数来递归查找集合的所有分区:defpartitions(set_):ifnotset_:yield[]returnforiinxrange(2**len(set_)/2):parts=[set(),set()]foriteminset_:parts[i&1].add(item)i>>=1forbinpartitions(parts[1]):yield[parts[0]]+bforpinpartitions(["a","b","c","d"]):print(p)有人可以帮我把它翻译成ruby吗?这是我目前所拥有的:defpartitions(set)ifnots
我是ruby开发的新手,我目前正在使用rails2.3.11在ruby1.8.7中开发一个项目,我想知道这种语言是否有与C#的linq等效的集合操作,例如where子句。谢谢。 最佳答案 Ruby中Linq的where等价于find_all检查documentationfortheEnumerableModule用于其他功能。 关于C#的LINQ用于在ruby中等效的集合操作,我们在StackOverflow上找到一个类似的问题: https://
我正在使用reform-railsgem为了在我的Rails项目中使用表单对象。我意识到表单对象对于我在下面使用的示例代码来说可能有点矫枉过正,但它仅用于演示目的。在我创建一个用户的表单中,与该用户记录关联的是两个user_emails。#models/user.rbclassUser请注意,我没有在User模型中使用accepts_nested_attributes_for:user_emails。在我看来,表单对象的要点之一是它可以帮助您摆脱使用accepts_nested_attributes_for,所以这就是为什么我试图在没有它的情况下这样做。我从thisvideo得到了这个
问题localhost:3000/users/不会显示我谦虚地进入,因为我是第一次尝试通过Rails教程。我在第10章,我已经花了5个小时解决这个问题。当我尝试访问localhost:3000/users/时出现错误(我相信这与factory_girl有关)解释了@users变量为空并且我忘记了为will_paginate传递一个集合对象。我目前在第10章第10.23节,每次运行时:$bundleexecrakedb:reset$bundleexecrakedb:populate$bundleexecrakedb:test:prepare我在解释时遇到错误rakeaborted!Fac
我正在为Mechanize而苦苦挣扎。我希望“单击”一组只能通过其位置(div#content中的所有链接)或其href来识别的链接。以上两种识别方法我都试过了,都没有成功。从文档中,我无法弄清楚如何根据链接在DOM中的位置而不是直接通过链接上的属性返回一组链接(用于单击)。其次,documentation建议你可以使用:href来匹配部分href,page=agent.get('http://foo.com/').links_with(:href=>"/something")但我让它返回链接的唯一方法是传递一个完全限定的URL,例如page=agent.get('http://foo
我有两个表与一个连接表连接-这只是伪代码:LibraryBookLibraryBooks我需要做的是,如果我有一个图书馆的id,我想获取该图书馆拥有的所有书籍所在的所有图书馆。因此,如果我有图书馆1,而图书馆1中有书A和B,而书A和B在图书馆1、2和3中,是否有优雅的(单行)方式在rails中执行此操作?我在想:l=Library.find(1)allLibraries=l.books.libraries但这似乎行不通。有什么建议吗? 最佳答案 l=Library.find(:all,:include=>:books)l.books
我想了解更多关于Rails路线的信息。成员和收藏#Exampleresourceroutewithoptions:resources:productsdomemberdoget'short'post'toggle'endcollectiondoget'sold'endend命名空间和作用域#Exampleresourceroutewithinanamespace:namespace:admindoresources:productsendscope:admindoresources:productsend约束,Redirect_to#Exampleresourceroutewithop