#kotlin #arraylist
#kotlin #arraylist
Вопрос:
У меня есть ArrayList<String>
таких данных:
download
download name:string
download name:string url:string
download test:string
list
print
print name:string
reload
reload name:string
Пример вывода должен выглядеть следующим образом:
download name:string url:string
download test:string // note this one does not get filtered
list
print name:string
reload name:string
Но я хотел бы удалить, download
поскольку download name:string
существует, а также удалить, download name:string
поскольку download name:string url:string
существует.
Я попытался использовать два списка массивов и кучу фильтров, но это стало чрезвычайно запутанным, и решения, которые я придумал, привели к пустому списку массивов.
Пример, который я пробовал:
val subCommands1 = arrayListOf<String>()
subCommands
.stream()
.sorted(Comparator.comparingInt(String::length))
.filter {
var found = false
subCommands1
.stream()
.sorted(Comparator.comparingInt(String::length))
.collect(Collectors.toList())
.reversed()
.forEach { comIt ->
if (comIt.startsWith(it)) {
found = true
}
}
if (!found) {
subCommands1.add(it)
}
!found
}
.collect(Collectors.toList())
Любые альтернативы тому, что я делаю, были бы оценены.
Комментарии:
1. Я не совсем понимаю определение вашей проблемы, но причина, по которой вы получаете пустой список, заключается в том, что вы фильтруете
subCommands
список с самим собой, что означает, что каждый элемент будет найден (найдено == true). Когда вы отменяете условие, все элементы снова найдены (найдено == true), но вы не фильтруете какие-либо элементы (!найдено == false), что приводит к получению исходного списка.2. Вы были правы, я попробовал это , и теперь это дает мне это , что тоже не очень хорошо
Ответ №1:
fun filterSubCommands(list: List<String>): List<String> {
if (list.size < 2) return ArrayList(list)
val result = ArrayList<String>()
list.asSequence().sorted().zipWithNext().forEach { (a, b) ->
if (!b.startsWith(a)) result.add(a)
}
result.add(list.last())
return result
}
Ответ №2:
Я придумал эту реализацию, предположив, что вы хотите всегда сохранять самую длинную строку доступных параметров:
fun main(): Unit {
val filteredCommands = HashSet<String>()
commands
.sortedByDescending { it.length }
.forEach { command ->
if (filteredCommands.find { it.startsWith(command) } == null) {
filteredCommands.add(command)
}
}
println(filteredCommands.toList().joinToString())
}
Вы можете запустить ее на этой игровой площадке.
Это может не сработать в зависимости от ваших командных правил, которые я не совсем понимаю, но это работает правильно для данного ввода.
Вот еще более функциональный подход, но он может показаться вам менее читаемым:
fun main(): Unit {
val filteredCommands = commands
.sortedByDescending { it.length }
.fold(emptySet<String>()) { filtered, command ->
if (filtered.find { it.startsWith(command) } == null)
filtered command
else
filtered
}
println(filteredCommands.toList().joinToString())
}
Вот игровая площадка с примером.