map、flatMap(流的扁平化)、split 的区别

日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)


 


1.flatMap:
    流的扁平化,最终输出的数据类型为一维数组Array[String]。
    被分割出来的每个数据都作为同一个数组中的相同类型的元素,最终全部被分割出来的数据都存储于同一个一维数组中。
    结论:多行数据被分割后都存储到同一个一维数组Array[String]中。
2.map:
    最终输出的数据类型为二维数组Array[Array[String]]。
    以相同分隔符分割出来的数据存储到同一个一维数组Array[String]中,一旦遇到分隔符所无法分割的位置(如遇到回车换行符时)时,
    便创建出一个新的一维数组Array[String],后面所分割的数据则都存储到新的一维数组Array[String]中,
    即分隔符所无法分割的位置作为新建一维数组Array[String]的标志。
    结论:一行数据就为一个一维数组Array[String],多行数据就有多个一维数组,最终多个一维数组一起被封装到同一个一维数组中。


=====================================================
 

        读取本地文件,实现文件内的单词计数。
        本地文件 /root/scala/words.txt 内容如下:
            hello me
            hello you
            hello her

        sc.textFile("file:///root///scala///words.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect
        输出 res0: Array[(String, Int)] = Array((hello,3), (me,1), (you,1), (her,1))
      解析:
        1.flatMap(_.split(" ")):输出数据 Array[String] = Array(hello,me,hello,you,hello,her)
            使用空格作为换行分隔符,被分割出来的每个数据都作为同一个数组中的相同类型的元素,最终全部被分割出来的数据都存储于同一个一维数组中。
            同时还会以回车换行符作为默认的分隔符,即回车换行符前面的数据也会被自动进行分割,而回车换行符后面所分割出来的数据同样存储于同一个一维数组中。
        2.map(_.split(" ")):输出数据 Array[Array[String]] = Array(Array(hello,me),(Array(hello,you),(Array(hello,her))
            使用空格作为换行分隔符,以相同分隔符分割出来的数据存储到同一个一维数组Array[String]中,最终输出的数据类型为二维数组Array[Array[String]]。
            同时还会以回车换行符作为新建一维数组Array[String]的标志,而回车换行符后面所分割的数据则都存储到新的一维数组Array[String]中。
        3.map((_,1)):
            map()首先表示遍历出数组中的每个元素。
            flatMap(_.split(" ")).map((_,1)):遍历出的是每个字符串 hello,me,hello,you,hello,her
            map(_.split(" ")).map((_,1)):遍历出出的是每个Array数组 Array(hello,me),Array(hello,you),Array(hello,her)    

=====================================================

val rdd1 = sc.parallelize(Seq(("one two three four five six seven"), ("one two three four five six seven"), ("one two three four five six seven")))
  
rdd1.map(_.split(" ")).collect
/*
res6: Array[Array[String]] = Array(Array(one, two, three, four, five, six, seven),
                                  Array(one, two, three, four, five, six, seven),
                                  Array(one, two, three, four, five, six, seven))
*/
 
rdd1.flatMap(_.split(" ")).collect
/*
res7: Array[String] = Array(one, two, three, four, five, six, seven,
                            one, two, three, four, five, six, seven,
                            one, two, three, four, five, six, seven)
*/
 
 
val rdd2 = sc.parallelize(Seq((1, "one two three four five six seven"), (2, "one two three four five six seven"), (3, "one two three four five six seven")))
 
rdd2.map(x => (x._1, x._2.split(" "))).collect
/*
res14: Array[(Int, Array[String])] = Array((1,Array(one, two, three, four, five, six, seven)),
                                           (2,Array(one, two, three, four, five, six, seven)),
                                           (3,Array(one, two, three, four, five, six, seven)))
*/
 
 
rdd2.map(x => 
{
    val x2 = x._2.split(" ")
    (x._1, x2.toIterable)
}).collect
/*
res4: Array[(Int, Iterable[String])] = Array((1,WrappedArray(one, two, three, four, five, six, seven)),
                                             (2,WrappedArray(one, two, three, four, five, six, seven)),
                                             (3,WrappedArray(one, two, three, four, five, six, seven)))
*/
 
rdd2.map(x => 
        {
        val x2 = x._2.split(" ")
        (x._1, x2.toIterable)
        }).flatMap 
      { x =>    
        val y = x._2
        for (w <- y) yield (x._1, w)
      }.collect
 
/*
res7: Array[(Int, String)] = Array((1,one), (1,two), (1,three), (1,four), (1,five), (1,six), (1,seven),
                                   (2,one), (2,two), (2,three), (2,four), (2,five), (2,six), (2,seven),
                                   (3,one), (3,two), (3,three), (3,four), (3,five), (3,six), (3,seven))
*/

===============================================================================================

scala> val s = "eggs, milk, butter, Coco Puffs" //除第一个单词外的每个单词前面都带有空格
s: String = eggs, milk, butter, Coco Puffs

scala> s.split(",")
res9: Array[String] = Array(eggs, " milk", " butter", " Coco Puffs") //除第一个单词外的每个单词前面都带有空格

scala> val s1 = "eggs,milk,butter, Coco Puffs" //只有最后一个单词的前面带有空格
s1: String = eggs,milk,butter, Coco Puffs

scala> s1.split(",")
res10: Array[String] = Array(eggs, milk, butter, " Coco Puffs")//只有最后一个单词的前面带有空格

scala> val s = "eggs, milk, butter, Coco Puffs"
s: String = eggs, milk, butter, Coco Puffs

scala> s.split(",").map(_.trim)  //trim 去掉“被分割出来的每个字符串前后面的”空格字符
res11: Array[String] = Array(eggs, milk, butter, Coco Puffs)
 


===============================================================================================

//要处理的字符串数据为:"中国|美国|英国"。目的是希望切开得到每个国家("中国","美国","英国"),然而结果却是("中","国","美","国","英","国")
import org.apache.spark.sql.functions._
split(data(field), "|"))  //data是一个Spark DataFrame,其中的field字段是由竖杠|隔开的字符串(如:"中国|美国|英国")

//要处理的字符串数据为:"中国|美国|英国"。而结果正是切开得到每个国家("中国","美国","英国")
import org.apache.spark.sql.functions._
split(data(field), "\\|"))

===============================================================================================

String中的 split(",") 和 split(",",-1) 的区别

1、当准备要被切割处理的字符串的最后一位有值(非分隔符)时,两者没有区别。
2、当准备要被切割处理的字符串的最后一位或者最后N位全部都是分隔符,而并非正常数据时,split(",")不会继续切分,并且不保留为null值,
   而split(",",-1)继续进行切分,并且保留出null值作为被切割出来的数据。


package stringsplit;
public class stringSplit 
{
     public static void main(String[] args) 
     {
          String line = "hello,,world,,,";
          String res1[] = line.split(",");
          String res2[] = line.split(",", -1);
          int i=1;
          for(String r: res1)
              System.out.println(i+++r);
          System.out.println("========================");
          i=1;
          for(String r: res2)
              System.out.println(i+++r);
     }

输出结果是:
1hello
2
3world
========================
1hello
2
3world
4      //保留为null值作为被切割出来的数据
5      //保留为null值作为被切割出来的数据
6      //保留为null值作为被切割出来的数据

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
mapflatMapScala中常用的函数操作,它们可以对集合中的元素进行处理和转换。 map函数接受一个函数作为参数,然后对集合中的每个元素应用该函数,并返回处理后的结果集。例如,对于一个整数集合,我们可以使用map函数将每个元素加倍: ``` val nums = List(1, 2, 3, 4, 5) val doubledNums = nums.map(x => x * 2) ``` 在这个例子中,map函数将传入的匿名函数`(x => x * 2)`应用于nums集合中的每个元素,并返回一个新的结果集doubledNums,其中每个元素都是原始元素的两倍。 而flatMap函数与map函数类似,但是它要求传入的函数返回一个List类型的结果。flatMap函数会将每个元素的处理结果集合合并成一个扁平化的结果集。例如,我们可以使用flatMap函数将一个字符串集合中的每个字符串拆分成单词: ``` val words = List("Hello World", "Scala is awesome") val flattenedWords = words.flatMap(x => x.split(" ")) ``` 在这个例子中,flatMap函数将传入的匿名函数`(x => x.split(" "))`应用于words集合中的每个字符串,并返回一个扁平化的结果集flattenedWords,其中包含了所有的单词。 总结来说,map函数用于对集合中的每个元素进行处理并返回结果集,而flatMap函数则要求传入的函数返回一个List类型的结果,并将所有的结果合并成一个扁平化的结果集。 希望这个解释对你有帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

あずにゃん

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值