2012-10-16 44 views
1

下面的代码打印一组文件名。如何基于现有数组值创建唯一值的集合

val pdfFileArray = getFiles() 
    for(fileName <- pdfFileArray){ 
    println(fileName) 
    } 

我想将此数组(pdfFileArray)转换为包含唯一文件扩展名的数组。

下面是在scala中做这件事的正确方法吗?

Set<String> fileNameSet = new HashSet<String> 
    val pdfFileArray = getFiles() 
    for(fileName <- pdfFileArray){ 
    String extension = fileName.substring(fileName.lastIndexOf('.')); 
    fileNameSet.add(extension) 
    } 

回答

1

你可以这样做:

val fileNameSet = pdfFileArray.groupBy(_.split('.').last).keys 

这是假设所有的文件名,你将有一个扩展,你只需要最后的扩展。即something.html.erb具有扩展名 '雇员再培训局'

+0

谢谢,但我认为你的代码需要稍微修改:pdfFileArray.groupBy(_。getName()。split('。')。last).keys –

1

有一个在Scala的集合称为distinct,它带走了集合中的所有重复项的方法。例如:

scala> List(1, 2, 3, 1, 2).distinct 
res3: List[Int] = List(1, 2, 3) 

这是你在找什么?

+0

这会给你不同的文件名全部,如何扩展? –

+1

通过扩展然后区分映射数组:array.map(_。lastIndexOf('。'))。distinct''。 –

2

这会妥善处理的文件不带扩展名(通过忽略)

val extensions = getFiles().map{_.split('.').tail.lastOption}.flatten.distinct 

所以

Array("foo.jpg", "bar.jpg", "baz.png", "foobar") 

成为

Array("jpg", "png") 
+0

我认为这是行不通的。如果split没有找到分隔符,split将返回一个元素的数组(整个字符串)。所以lastOption将永远是一个。这意味着你会得到Array(“jpg”,“png”,“foobar”) – rjsvaljean

+0

啊你是对的,但'.tail.lastOption'确实可行,我会编辑我的答案。 –

+0

是的。你是对的。这样可行。 – rjsvaljean

1

为了完整起见:

List("foo.jpg", "bar.jpg").map(_.takeRight(3)).toSet 

这里我假设所有的扩展名都是3个字符。转换为Set,就像.distinct方法(顺便说一下,在下面使用可变集)在其他答案中为您提供了独特的项目。

+0

为什么Set“在下面使用可变集合? –

+0

@ user470184,好吧,这部分实际上涉及.distinct,而不是Set,对不起,如果我把你搞糊涂了 –

1

您还可以使用正则表达式做到这一点,这让更广泛的解决方案,因为你可以重新定义表达式来匹配你想要的东西:

val R = """.*\.(.+)""".r 
getFiles.collect{ case R(x) => x }.distinct 
相关问题