简单汇总了一些常见的Scala数组算子
def main(args: Array[String]): Unit = {
val arr1 = Array(1, 2, 3, 4)
val first = arr1(0)
val newArr = arr1.map(x => x * 2)
newArr.mkString(",") //拼接字符串
newArr.mkString("(", "*", ")")
//合并集合
val a = Array(1, 2)
val b = Array(3, 4)
b ++ a
//++:
val c = List(1, 2) //数组默认值不可变类型
val d = scala.collection.mutable.LinkedList(3, 4) //可变
val e = c ++: d //c的类型会和 :后面的类型一样,如果不加:则有可变就可变
println(c.getClass.getName)
//拼接
a :+ 3
println(a.mkString(","))
// "/:"对数组中所有的元素从左向右遍历,进行相同的迭代操作,foldLeft 的简写
val f = (10 /: a) ((x, y) => x + y)
println(f)
val g = (10 /: a) ((x, y) => {
println("x:" + x, "y:" + y);
x + y
})
println(g + "-4/27-----------------------------------------")
//将数组中的元素逐个添加到 StringBuilder 中
val h = new StringBuilder()
println(a.addString(h))
//将数组中的元素逐个添加到 StringBuilder 中,每个元素用 sep 分隔符分开
b.addString(h, "&")
//聚合计算 seq中的数字先随机组合运算,然后在combine中计算(seq里已组合的结果),两边同时运行 aggregate是柯里化方法,参数是两个方法
def seqno(m: Int, n: Int): Int = {
val s = "seq_op=%d+%d"
println(s.format(m, n))
m + n
}
def combin(m: Int, n: Int): Int = {
val s = "combine_op=%d+%d"
println(s.format(m, n))
m + n
}
var q = List(1, 2, 3, 4)
q.aggregate(0)(seqno, combin) //不分区
q.par.aggregate(0)(seqno, combin) //分区
println("-------------------------------------------------------")
//聚合函数
val aa = List(Array(3, 5, 4), Array(7, 7))
def seq(m: (Int, Int), n: Array[Int]): (Int, Int) = {
(m._1 + n.sum, m._2 + n.size)
}
def combine(m: (Int, Int), n: (Int, Int)): (Int, Int) = {
(m._1 + n._1, m._2 + n._2)
} //返回总的(sumAll,size)
//输入参数(sum,cnt) 是seq的出参,seq是combine的入参
var cnt = aa.par.aggregate(0, 0)(seq, combine)
println(cnt)
println(cnt._1 / cnt._2.toDouble)
println("-4/28------------------------------------------------")
//获取指定索引处的元素
a.apply(1)
//获取 index 索引处的字符,这个方法会执行一个隐式的转换,将 Array[T] 转换为 ArrayCharSequence,只有当 T 为 Char 类型时,这个转换才会发生
var chars = Array('a', 'b', 'c')
println(chars.charAt(0)) //a
//创建一个副本
val aaa = a.clone()
println(aaa.mkString(",")) //a(1,2)
//通过执行一个并行计算(偏函数),得到一个新的数组对象
val fun1: PartialFunction[Int, String] = {
case 1 => "S"
case _ => "A"
}
val bb = a.collect(fun1)
println(bb.mkString(",")) //打印int数组转为大写字母 //S,A
//在序列中查找第一个符合偏函数定义的元素,并执行偏函数计算
val i = Array(1, 30, 34)
println(i.collectFirst(fun1)) //S
var ii = i.collectFirst({ case x: Int => println("可以直接写") })
// .getOrElse如果没有值,则赋一个值
//combinations 表示组合,这个排列组合会选出所有包含字符不一样的组合,但不考虑顺序,
// 对于 “abc”、“cba”,视为相同组合,参数 n 表示序列长度,就是几个字符为一组
val va1 = i.combinations(3)
va1.foreach(x => {
println(x.getClass.getName)
println(x.mkString(","))
})
//判断序列中是否包含指定对象
val j = List(1, 2, 3, 4)
println(j.contains(5)) //false
//判断当前序列中是否包含另一个序列
println("a:" + a.mkString(","))
println(j.containsSlice(a))
//将当前数组元素复制到另一个数组中
var k = new Array[Int](5)
j.copyToArray(k)
j.copyToArray(k, 4) //把j拷贝到k,从第4位开始(超出不算)
j.copyToArray(k, 6, 3) //把j拷贝到k,从第2位开始复制,拷贝长度为3
println("new k:" + k.mkString(","))
//将数组中的元素复制到 Buffer 中
import scala.collection.mutable.ArrayBuffer
val jj: ArrayBuffer[Int] = ArrayBuffer()
j.copyToBuffer(jj)
println(jj.mkString(",")) //1,2,3,4
//判断两个序列的长度以及对应位置元素是否符合某个条件。
// 如果两个序列具有相同的元素数量并且 p(x, y)=true,则返回 true
println(j.corresponds(k)(_ > _)) //后面是判断条件 检查长度是否相等
//统计符合条件的元素个数
println(j.count(x => x < 3))
//返回当前数组与另一个数组的差集
val ll = j.diff(k)
println(ll.mkString(",")) // 2
//去除当前集合中重复的元素,只保留一个
var kk = k.distinct
println(kk.mkString(","))
//将当前数组中前n个元素去除,返回一个新数组
var jjj = j.drop(2)
println("j:" + j.mkString(","))
println("jjj:" + jjj.mkString(","))
//将当前数组中尾部 n个元素去除,返回一个新数组
var j1 = j.dropRight(2)
println("j1:" + j1.mkString(","))
// 去除当前数组中符合条件的元素,返回剩余的数组,这个需要一个条件,
// 就是从当前数组的第一个元素起,就要满足条件,
// 直到碰到第一个不满足条件的元素结束(即使后面还有符合条件的元素)否则返回整个数组
val kkk = k.dropWhile(x => x < 2)
println(kkk.mkString(","))
//判断当前序列是否以某个序列结尾
println(k.endsWith(a))
//判断当前数组是否包含符合条件的元素
print(k.exists(x => x == 3))
println(k.exists(x => x > 2))
//取得当前数组中符合条件的元素,组成新的数组返回(filterNot就是返回不满足条件的)
val lll = k.filter(x => x > 2)
println(lll.mkString(","))
//查找第一个符合条件的元素,返回 Option
val m = k.find(x => x > 2)
println(m) // Some( )
//对当前序列的每个元素进行操作,结果放入新序列返回,参数要求是 GenTraversableOnce 及其子类
println(k.flatMap(x => 1 to x).mkString(","))
val str = List(Array("a", "b"), Array("c", "d"))
val zip = str.flatMap(x => x) //把东西压到一起
println(zip.mkString(","))
//扁平化,将二维数组的所有元素组合在一起,形成一个一维数组返回(同上)
val zip1 = str.flatten
println(zip1.mkString(","))
//对序列中的每个元素进行二元运算,和aggregate有类似的语义,但执行过程有所不同(10是初始值)
println(k.fold(10)((x, y) => {
println("seq", x, y);
x + y
}))
//检测序列中的元素是否都满足条件 p,如果序列为空,则返回 true
println(k.forall(x => x > 0))
//遍历序列中的元素,进行 f 操作
k.foreach(x => print(x + " "))
//按条件分组,条件由 f匹配,返回值是Map类型,每个 key对应一个数组
val o = k.groupBy(x =>
x match {
case x if (x < 2) => "small"
case _ => "big"
})
o.foreach(x => println(x._1, x._2.foreach(println)))
println("------------------------------------------------")
//按指定数量分组,每组有 size 个元素,返回一个迭代器
val qq = k.grouped(3).toList
qq.foreach(x => println("第 " + (qq.indexOf(x) + 1) + " 组: " + x.mkString(",")))
//返回序列的第一个元素,如果序列为空,将引发错误
println(a.head)
//返回序列的第一个元素的 Option 类型对象,如果序列为空,则返回 None
println(a.headOption)
//返回元素 elem 在序列中第一次出现的索引
println(k.indexOf(4)) //3
//返回元素 elem 在序列中第一次出现的索引,指定从索引 from 开始查找
println(k.indexOf(1, 2)) //4
//返回元素 elem 在序列中最后一次出现的索引 指定在索引 end 之前(包括)的元素中查找
println(k.lastIndexOf())
//检测当前序列中是否包含序列 that(a),并返回第一次出现该序列的索引 指定从索引 from 开始查找
println(k.indexOfSlice(a, 1))
//检测当前序列中是否包含序列 that,并返回最后一次出现该序列的索引,指定在索引 end 之前(包括)的元素中查找
println(k.lastIndexOfSlice(a, 5))
//返回当前序列中第一个满足条件 p 的元素的索引 指定从索引 from 开始查找
println(k.indexWhere(x => x > 2, 3))
//返回当前序列索引集合
println(k.indices.mkString(",")) //0,1,2,3,4
//返回当前序列中不包含最后一个元素的序列
println(k.init.mkString(",")) //1,2,3,4
//对集合中的元素进行 init 迭代操作,
// 该操作的返回值中, 第一个值是当前序列的副本,最后一个值为空,
// 每一步都进行 init 操作,上一步的结果作为下一步的操作对象
val w = k.inits.toList
for (i <- 0 until w.length) {
val ww = "k第 %d 个值: %s"
println(ww.format(i + 1, w(i).mkString(",")))
}
//取两个集合的交集
println(k.intersect(a).mkString(","))
//判断序列中是否存在指定索引
println(k.isDefinedAt(5)) //false
//判断序列是否为空
println(k.isEmpty) //false
//判断序列是否不为空
println("------" + k.nonEmpty) //true
//判断序列是否可以反复遍历,该方法是 GenTraversableOnce 中的方法,
// 对于 Traversables 一般返回 true,
// 对于 Iterators 返回 false,除非被复写
println(k.isTraversableAgain) //数组可复写
//生成当前序列的迭代器
val s = k.iterator
println(s.isTraversableAgain) //迭代器不可复写
//返回序列的最后一个元素,如果序列为空,将引发错误
println(k.last)
//比较序列的长度和参数 len(自己设),返回序列的长度 - len
println(k.lengthCompare(3))
//对序列中的元素进行 f 操作,返回生成的新序列
println(a.map(x => x * 10).mkString(","))
//返回序列中最大的元素/最小的元素
println(k.max)
println(k.min)
//返回序列中符合条件的第一个元素
println(k.maxBy(x => x > 3))
//返回序列中不符合条件的第一个元素
println(k.minBy(x => x == 1))
//填充序列,如果当前序列长度小于 len,那么新产生的序列长度是 len,
// 多出的几个位值填充 elem,如果当前序列大于等于 len ,则返回当前序列
println(a.mkString(","))
println(a.padTo(5, 0).mkString(","))
//返回一个并行实现,产生的并行序列不能被修改
val t = a.par
println(t.mkString(","))
//按条件将序列拆分成两个数组,满足条件的放到第一个数组,其余的放到第二个数组,
// 返回的是包含这两个数组的元组
val tt: (Array[Int], Array[Int]) = k.partition(x => x % 2 == 0)
println("偶数:" + tt._1.mkString(","))
println("奇数:" + tt._2.mkString(","))
//批量替换,从原序列的 from 处开始,用后面的 几 个元素,将被替换成序列 that
println(k.patch(2, a, 2).mkString(","))
//表示排列,这个排列组合会选出所有排列顺序不同的字符组合,
// permutations 与 combinations 不同的是,相同的组合考虑排列,对于 “abc”、“cba”,视为不同的组合
k.permutations.toList.foreach(x=>println("--"+x.mkString(",")))
//给定一个条件 p,返回一个前置数列的 长度,这个数列中的元素都满足 p(从前往后开始,第一个不满足就结束)
println(k.prefixLength(x => x < 3))
//返回所有元素乘积的值
println(k.product)
//同 fold,不需要初始值
// def seqno(m: Int, n: Int): Int = {
// val s = "seq_exp = %d + %d"
// println(s.format(m, n))
// m + n
// }
//
// def combine1(args: Array[String]) {
// val a = Array(1, 2, 3, 4)
// val b = a.reduce(seqno)
// println("b = " + b)
// /**
// * seq_exp = 1 + 2
// * seq_exp = 3 + 3
// * seq_exp = 6 + 4
// * b = 10
// */
//反转序列
println(k.reverse.mkString(",")) //1,4,3,2,1
//生成反向迭代器
k.reverseIterator.foreach(x => println(x + " "))
//同 map,方向相反
println(k.reverseMap(x => x * 10).mkString(","))
//判断两个序列是否顺序和对应位置上的元素都一样
val k1 = k.clone()
println(k.sameElements(k1))
println(k.sameElements(a))
//同fold,scan会把每一步的计算结果放到一个新的集合中返回 而fold返回的是最后的结果
println(k.scan(5)(_ + _).mkString(","))
//同 foldLeft,从左向右计算,每一步的计算结果放到一个新的集合中返回
println(k.mkString(","))
println(k.scanLeft(5)(_ + _).mkString(","))
//同 foldRight,从右向左计算,每一步的计算结果放到(从右向左放)一个新的集合中返回
println(k.scanRight(5)(_ + _).mkString(","))
//从序列的 from 开始向后查找,返回满足条件 p 的连续元素的长度,只返回第一个
println(k.segmentLength(x => x < 3, 3))
//产生一个引用当前序列的 sequential 视图
println(k.seq.mkString(","))
//返回当前序列中从 from 到 until 之间的序列,不包括 until 处的元素
println(k.slice(1, 3).mkString("-"))
//返回当前序列中从 from 到 until 之间的序列,不包括 until 处的元素
println(k.view(1, 3).mkString(" "))
//滑动,从第一个元素开始,每个元素和它后面的size-1个元素组成一个数组,最终组成一个新的集合返回,当剩余元素个数不够 size 时,则结束。
//该方法可以设置步长 step,每一组元素组合完后,下一组从上一组起始元素位置 + step 后的位置处开始
val u = k.sliding(2, 3).toList
for (i <- 0 to u.length - 1) {
println("第%d组:%s".format(i + 1, u(i).mkString(",")))
}
//按指定的排序规则对序列排序
println("正序" + k.sortBy(x => x).mkString(","))
println("倒序" + k.sortBy(x => -x).mkString(","))
//从指定位置开始,把序列拆分成两个元组
println(k.splitAt(3)._1.mkString(","))
println(k.splitAt(3)._2.mkString(","))
//判断序列是否以某个序列开始
println(k.startsWith(a))
//判断序列从指定 偏移处 是否以某个序列开始
println(k.startsWith(a,1))
//返回 toString 结果的前缀
println(a.toString().stringPrefix)
//返回 start 和 end 间的字符序列,不包含 end 处的元素
println(chars.mkString(","))
println(chars.subSequence(1, 2).toString)
//返回当前序列中不包含第一个元素的序列
println(k.tail.mkString(","))
//同 inits,每一步都进行 tail 操作
for (i<-0 until k.toList.length){
}
//返回当前序列中,前 n 个元素组成的序列
println(k.take(2).mkString(","))
//返回当前序列中,从右边开始,后 n 个元素组成的序列
println(k.takeRight(2).mkString(","))
//返回当前序列中,从第一个元素开始,满足条件的连续元素组成的序列
println(k.takeWhile(x => x > 2).mkString(","))
//将序列转换成 Array 类型
k.toArray.mkString(" ")
//将序列转换成 Buffer 类型
k.toBuffer.mkString(" ")
//将序列转换成 IndexedSeq 类型
k.toIndexedSeq.mkString(" ")
//将序列转换成可迭代的类型
k.toIterable.mkString(" ")
//将序列转换成迭代器,同 iterator 方法
k.toIterator.mkString(" ")
//将序列转换成 List 类型
k.toList
//将序列转转换成 Map 类型,需要被转化序列中包含的元素是 Tuple2 <K,V> 类型
//k.toMap
//将序列转换成 Seq 类型
k.seq
//将序列转换成 Set 类型
k.toSet
//将序列转换成 Stream 类型
k.toStream
//将序列转换成 Vector 类型
k.toVector
//矩阵转置,二维数组行列转换
val r=Array(Array(1,2),Array(3,4),Array(5,6))
r.transpose.foreach(x=>println(x.mkString(" ")))
/*1 3 5
2 4 6
*/
//合并两个序列,同操作符 ++
println(a.union(k).mkString(" "))
//将含有两个二元组的数组,每个元组的第一个元素组成一个数组,第二个元素组成一个数组,
// 返回包含这两个数组的元组
val r1=Array((1,2),(3,4))
println(r1.unzip._1.mkString(" "))
println(r1.unzip._2.mkString(" "))
//将含有两个二元组的数组,每个元组的第一个元素组成一个数组,第二个元素组成一个数组
// 返回包含这两个数组的元组
val r3=Array((1,2,3),(3,4,5),(5,6,7))
println(r3.unzip3._1.mkString(" "))
println(r3.unzip3._2.mkString(" "))
println(r3.unzip3._3.mkString(" "))
//将序列中 i 索引处的元素更新为 x
k.update(4,5)
println(k.mkString(","))
//将序列中 i 索引处的元素更新为 x,并返回替换后的数组
println(k.updated(4, 5).mkString(" "))
//根据条件 p 过滤元素
println(k.withFilter(x => x < 3).map(x => x).mkString(","))
//将两个序列对应位置上的元素组成一个 元组数组,要求两个序列长度相同
val kc=k.clone()
println(k.zip(k1).mkString(" "))
//同 zip ,但是允许两个序列长度不同,不足的自动填充,
// 如果前面数组短则用0填充,后面数组短则用6填充
println(a.zipAll(k,0,6).mkString(" "))
//序列中的每个元素和它的索引组成一个元组数组
}