scala合并文件,删除具有相同字段的记录

合并结构相同,内容格式为json的两个文件,用scala代码实现。
编译环境:Scala IDE for Eclipse

1.下面是详细的代码:
package hyp
import scala.util.parsing.json._
import com.common.pinyin
import scala.io.Source
import scala.collection.mutable.Set
import java.io.PrintWriter;
import java.io.File;

/**
 * IO操作
 * @date Apr 24, 2017
 * @author hyp
 *
 */
object TestIO {
  def main(args: Array[String]): Unit = {
    val onePath = "C:/Users/Administrator/Desktop/test/1.txt";
    val twoPath = "C:/Users/Administrator/Desktop/test/2.txt";
    val threePath = "C:/Users/Administrator/Desktop/test/3.txt";
    val actionIO = new ActionIO()
    actionIO.mergeFile(onePath, twoPath, threePath)
  }
}
class ActionIO {

  /**
   * 合并文件,删除具有相同字段url的记录,
   * @date Jun 15, 2017
   * @author hyp
   * @param oneFilePath
   * @param twoFilePath
   * @param threeFilePath 合并后文件
   */
  def mergeFile(oneFilePath: String, twoFilePath: String, threeFilePath: String) {
    //1.读文件oneFilePath,并存为oneSet,url存为ourlSet
    val oneSet = Source.fromFile(oneFilePath).getLines().toSet
    val it = oneSet.iterator;
    var ourlSet: Set[String] = Set()
    while (it.hasNext) {
      val labeljson = JSON.parseFull(it.next())
      labeljson match {
        case Some(labelmap: Map[String, Any]) =>
          val url = labelmap("url").toString().replaceAll(" ", "")
          ourlSet.+=(url) //NOTE1:注意两者的区别urlSet.+(url)
        case _ => println(labeljson.toString());
      }
    }
    println("ourlSet.length===" + ourlSet.size)

    //2.读文件twoFilePath,并存为twoSet,url存为turlSet
    val twoSet = Source.fromFile(twoFilePath).getLines().toSet
    val its = twoSet.iterator;
    var turlSet: Set[String] = Set()
    while (its.hasNext) { 
      val labeljson = JSON.parseFull(its.next())
      labeljson match {
        case Some(labelmap: Map[String, Any]) =>
          val url = labelmap("url").toString().replaceAll(" ", "")
          turlSet.+=(url) 
        case _ => println(labeljson.toString());
      }
    }
    println("turlSet.length===" + turlSet.size)

    //3.重合的url存为thSet,ourlSet与turlSet相交
    val thSet = ourlSet.&(turlSet)
    //val thSet = ourlSet.intersect(turlSet) //同上,相交
    println("重合的url:" + thSet.size + " 条")
    //    thSet.foreach(println)

    //4.删除oneSet中包含重合url的记录,fSet
    val filterSet = oneSet.filter { x =>
      thSet.forall { a =>
        !x.contains(a)
      }
    }
    println("过滤后的oneSet:" + filterSet.size + "条")

    //5.两个set并集,并存为txt
    val sSet = twoSet.union(filterSet)
    println("并集:" + sSet.size + "条")
    val writer = new PrintWriter(new File(threeFilePath))
    sSet.foreach { x =>
      writer.write(x + "\n")
    }
    writer.close()

    println("执行成功!")

  }
}
2.项目中用到的1.txt和2.txt格式都一样,可以按照这种格式自行编造数据,如下:
{"_id":{"$oid":"593f69e81d41c80a84c9728d"},"category":"车系首页","tit":"【九龙A52010款2.4L 精英型4RB2报价_图片_参数】_九龙汽车九龙A5怎么样_爱卡汽车","url":"http://newcar.xcar.com.cn/m18568/","address":"爱卡汽车\u003e轻客\u003e九龙A5\u003e2010款2.4L精英型4RB2\u003e车型首页"}
3.eclipse中执行Run as ->scala application ,控制台输出结果,并查看合并后的文件。

这里写图片描述

4.开发问题记录:
  1. scala中Iterator只能访问一次。scala读文件Source.fromFile(twoFilePath).getLines()得到的是一个Iterator[String]对象,该对象只能访问一次,再次操作必须重新执行Source.fromFile(twoFilePath).getLines(),重新获取Iterator[String]对象,解决这个问题是把Iterator[String]转化为Array,List,Map,Set等,这样就可以一次读取文件,多次访问或者操作了。
    原代码:

        val linesIterator= Source.fromFile(filePath).getLines()

    改为:

        val linesSet = Source.fromFile(filePath).getLines().toSet

    相关参考链接:http://www.cnblogs.com/lovegmail/p/4818883.html

  2. 集合Set操作+与+=是不相同的,+是添加一个元素并生成新的Set,而+=是在原Set中添加一个元素。
  3. 代码没有忽略空格行,如果文件中有空格行的话可能会出错。
  4. forAll循环,返回boolean值,当所有元素都满足条件时返回true,常与filter结合使用实现双重循环。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值