I want to filter the list for carMakes that have a...
# getting-started
o
I want to filter the list for carMakes that have a constraint on the
name
field, then reconstruct this sortedmap agian
p
Something like that? https://pl.kotl.in/HySGJC9UE
Or do you want to have a new map?
o
ahh
entries
i will test this, thank you
why’d you go with a TreeMap though, I said SortedMap
thankful of course for you taking the time to write it, but why pick this peculiar type to show an example
you can do this with filter > map
p
TreeMap
is first implementation of
SortedMap
that I found. Kotlin’s
.toSortedMap()
also creates
TreeMap
o
p
Nice!
Just note, that
mapValues
creates a new map and it is not
SortedMap
.
o
yes that’s fine, I had changed the receiving function’s signature to Hashmap, i do
toSortedMap
inside it, i was doing it twice before, it was wrong
hm, there’s another problem with the keys
that if I dont find any of the value list items matching what i want, the key can remain with an empty result
can i mapValues and chain that with mapKeys,
tosortedMap
isnt letting me do this because it needs a comparator
the datastructure im using is for example “A, 20 items starting with A”, “B, 2 items starting with B”, etc.
ok it worked
very easy
p
If I understood correctly what your snippet does, then I would recommend:
Copy code
val carMakesMap = carMakes.values
    .flatten()
    .filter { carMake -> carMake.name.contains(newText, ignoreCase = true) }
    .groupBy { it.name.first() }
Or maybe:
Copy code
val carMakesMap = carMakes
    .mapValues { (_, value) ->
        value.filter {carMake -> carMake.name.contains(newText, ignoreCase = true) }
    }
    .filterValues { it.isNotEmpty() }
k
You can avoid a lot of intermediary collections by replacing
.functionalOperator { ... }.toCustomCollectionImpl()
with
.functionalOperatorTo(CustomCollectionImpl()) { ... }
so you could replace
.mapValues { ... }.toSortedMap()
with
.mapValuesTo(TreeMap()) { ... }
👍 1
☝🏻 1
o
didnt understand what you suggested kevin
the following works fine
Copy code
carMakes.mapValues { entry ->
                            entry.value.filter { carMake ->
                                carMake.name.contains(newText, ignoreCase = true)
                            }.groupBy { it.name.first() }.toMap(carMakesMap)
                        }
but i am still unable to then after all of this, filter the keys to only take those who have notEmpty values (the list belonging to that key is empty because none of its items matched that key (entered through searchbar))
like so
Copy code
carMakes.mapValues { entry ->
    entry.value.filter { carMake ->
        carMake.name.contains(newText, ignoreCase = true)
    }.groupBy { it.name.first() }.toMap(carMakesMap)
}.filterKeys { carMakes[it]!!.isNotEmpty() }
k
If you find yourself doing a functional transform like
mapValues
, and then the output collection isn't in a format that you want so you do something like
toMap(...)
or
toSortedMap()
or anything like that, you could use the version of the transform ending in
To
, like
mapValuesTo
and specify a collection to output into as the first parameter
o
so I wouldnt have to worry about the transformation at the end?
k
trying to understand the full problem. So the
Char
keys are like, the first letter in the car make? Like the map is:
Copy code
[
  'a': [],
  'b': [],
  'c': [CarMake("Chevy")],
  'd': [CarMake("Dodge")],
  ...
]
?
and you want to filter the map based on a predicate against the name of each CarMake object, keeping the map sorted?
o
terribly sorry, here’s the screenshot that explains what the usecase is http://snpy.in/EM3Bym
only the trimming of the keys is left to do, after the trimming of the values is done
so far it hasnt worked to follow up on this map by doing
.filterKeys
on it after i filtered the values
k
you mean you want to remove the characters that have no matches?
o
the keys that have values which are empty <-- thats how i think of it
so thats how im writing it
so far it hasnt worked and still produces this http://snpy.in/QbxD4L
what I did was just append all the filtering code like above, with this
.filterKeys { carMakes[it].isNotEmpty() }
why wouldnt that work, it looks correct
oh..but the resulting map was already sent to carMakesMap before this filterKeys took place
nah that last part is wrong, not sure how it do it
k
Copy code
carMakes
    .mapValuesTo(TreeMap()) { (_, values: List<String>) -> values.filter { it.contains(filter, ignoreCase = true) }}
    .filterTo(TreeMap()) { (_, values) -> values.isNotEmpty() }
is there something about this that wouldn't work?
o
i was not able to try what you suggestd, syntax was weird
i can copy this though
you gotta epxlain it if it works though 😛
k
I feel like you could also do
Copy code
carMakes
    .values
    .flatten()
    .filter { it.contains(filter, ignoreCase = true) }
    .groupByTo(TreeMap()) { it[0] }
I feel the first would likely be more efficient though
that 2nd one would be more performant if you do
asSequence()
in the middle too.
.values.asSequence().flatten()....
o
👍🏻