Home > Enterprise >  How to display items without showing duplicates
How to display items without showing duplicates

Time:05-12

I try to create a tree of files with indentation without displaying duplicate files. Currently I have done this:

val listOfDisplayPaths : List<String> = listOf(
        "/home/josh/project/app/src/index.js",
        "/home/josh/project/app/images/logo.png",
        "/home/peter/.bashrc",
        "/var/log",
        "/usr/lib/node14",
        "/opt/apache2",
        "/etc/hosts"
)

fun displayPaths(paths: List<String>): String {
    val sb = StringBuilder()
    var pathIndented = ""

    for (p in paths) {
        val path = p.split("/")
        
        for (file in path){
            val index = path.indexOf(file)
            val pathWithoutIndent = sb.append(file   "\n")
            val space = addSpace(index)
            pathIndented = sb.append(String.format(space, pathWithoutIndent)).toString()
        }
    }
    return pathIndented
}

fun addSpace(index: Int): String {
    if (index == 0){
        return "- "
    }
    val space = "    "
    return space.repeat(index)
}

fun main(vararg args: String) {
    displayPaths(listOfDisplayPaths)
}

Current result:

- home
    josh
        project
            app
                src
                    index.js
                        
- home
    josh
        project
            app
                images
                    logo.png
                        
- home
    peter
        .bashrc
            
- var
    log
        
- usr
    lib
        node14
            
- opt
    apache2
        
- etc
    hosts

Expected result:

- home
    josh
        project
            app
                src
                    index.js
                images
                    logo.png
    peter
       bashrc
- var
    log
- usr
    lib
        node14
- opt
    apache2
- etc
    hosts

How to not display duplicate file titles while keeping the current indentation ?

I also have this warning without using print:

solution.kt:88:17: warning: parameter 'args' is never used fun main(vararg args: String){
                                                                    ^

How can I solve it?

EDIT: I have replaced

fun main(vararg args: String) {
    displayPaths(listOfDisplayPaths)
}

By:

fun main() {
    displayPaths(listOfDisplayPaths)
}

To solve the warning

Thanks by advance

CodePudding user response:

This is a perfect application for Trie data structure. You just put all the paths into the prefix tree and then traverse the tree creating an appropriate path string.

UPD: You might want to store children as a hash map, instead of a list for better search performance.

import java.util.LinkedList

class Trie {
    
    data class Node(val value: String, var isFile: Boolean = false, val children: MutableList<Node> = LinkedList<Node>()) {
        fun traversePath(currString: StringBuilder, tabs: Int = 1): String {
            if (tabs == 1) currString.append("- ")
            else repeat(tabs) { currString.append("  ") }
            currString.append("${this.value}")
            currString.append("\n")
            
            if (this.isFile) return currString.toString()
            this.children.forEach { it.traversePath(currString, tabs   1) }
            return currString.toString()
        }
    }
    
    val root = Node("")
    fun add(path: List<String>) {
        if (path.isEmpty()) return
        var currNode = root
        for (name in path) {
            var nextNode = currNode.children.firstOrNull { it.value == name }
            if (nextNode == null) {
                nextNode = Node(name)
                currNode.children.add(nextNode)
            }
            currNode = nextNode
        }
        currNode.isFile = true
    }
}

val listOfDisplayPaths : List<String> = listOf(
        "/home/josh/project/app/src/index.js",
        "/home/josh/project/app/images/logo.png",
        "/home/peter/.bashrc",
        "/var/log",
        "/usr/lib/node14",
        "/opt/apache2",
        "/etc/hosts"
)

fun displayPaths(paths: List<String>): String {
    val sb = StringBuilder()
    val trie = Trie()
    for (path in paths) trie.add(path.trim('/').split("/"))
    
    for (node in trie.root.children) {
        sb.append(node.traversePath(StringBuilder()))
        sb.append('\n')
    }
    return sb.toString()
}

fun main() {
    println(displayPaths(listOfDisplayPaths))
}
  • Related