4

I'm successfully getting data back through StreamBuilder and need to sort it. How can I sort a Map of my snapshot data by keys? Also, If you give an example of doing this my value that would help also. I think I want to do a SplayTreeMap, but if there is a better way please provide. Here is my dictionary...

{Vid2: {imageString: https://i.ytimg.com/vi/Amq-qlqbjYA/mqdefault.jpg, title: BLACKPINK - '마지막처럼 (AS IF IT'S YOUR LAST)' M/V, rank: 2, videoID: Amq-qlqbjYA}, Vid10: {imageString: https://i.ytimg.com/vi/KSH-FVVtTf0/mqdefault.jpg, title: EXO 엑소 'Monster' MV, rank: 10, videoID: KSH-FVVtTf0}, Vid6: {imageString: https://i.ytimg.com/vi/BVwAVbKYYeM/mqdefault.jpg, title: [MV] BTS(방탄소년단) _ DOPE(쩔어), rank: 6, videoID: BVwAVbKYYeM}, Vid3: {imageString: https://i.ytimg.com/vi/m8MfJg68oCs/mqdefault.jpg, title: [MV] BTS(방탄소년단) _ Boy In Luv(상남자), rank: 3, videoID: m8MfJg68oCs}, Vid4: {imageString: https://i.ytimg.com/vi/9pdj4iJD08s/mqdefault.jpg, title: BLACKPINK - '불장난 (PLAYING WITH FIRE)' M/V, rank: 4, videoID: 9pdj4iJD08s}, Vid1: {imageString: https://i.ytimg.com/vi/3s1jaFDrp5M/mqdefault.jpg, title: EPIK HIGH - 'BORN HATER' M/V, rank: 1, videoID: 3s1jaFDrp5M}, Vid8: {imageString: https://i.ytimg.com/vi/3QAcvc4Ysl0/mqdefault.jpg, title: LONNI - LA KPOP 2, rank: 8, videoID: 3QAcvc4Ysl0}, Vid5: {imageString: https://i.ytimg.com/vi/2ips2mM7Zqw/default.jpg, title: BIGBANG - 뱅뱅뱅 (BANG BANG BANG) M/V, rank: 5, videoID: 2ips2mM7Zqw}}

I would like to display it either by keys... Vid1, Vid2, Vid3...

or by values like rank ie... Vid1:rank "1", Vid2: rank "2", Vid3: rank "3"...

Charles Jr
  • 8,333
  • 15
  • 53
  • 74

1 Answers1

8

If the source is a map, this should do what you want:

final sorted = new SplayTreeMap<String,dynamic>.from(map, (a, b) => a.compareTo(b));

DartPad example

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    It works except it reads back 1, 10, 2, 3, 4... Any ideas on how to get it to read numerically?? – Charles Jr Dec 06 '17 at 23:50
  • ... Or by key 'rank'? – Charles Jr Dec 07 '17 at 01:04
  • 2
    You can customize the order function (`(a, b) => a.compareTo(b)`) to remove the `Vid` prefix and parse the rest of the string as integer and call `.compareTo` on these integer values or use `(a, b) => map[a]['rank'].compareTo(map[b]['rank'])` – Günter Zöchbauer Dec 07 '17 at 04:07
  • 1 more thing... The sorting seems to only return 1 matching value set i.e. if there are there are 2 nodes with {rank: 10} I'm getting the first but not the second or third. How can I include all nodes in my SplayTreeMap? – Charles Jr Dec 11 '17 at 05:17
  • Seems like you need to use the `isValidKey` Method here... `SplayTreeMap.from( Map other, [ int compare( K key1, K key2 ), bool isValidKey( potentialKey ) ])` but its not clear how – Charles Jr Dec 11 '17 at 05:24
  • Why do you think that you need `isValidKey`. The dartpad seems to be working, isn't it? – Günter Zöchbauer Dec 11 '17 at 05:58
  • Yes, but my example has different "Vids" when I change a few "rank" values to match each other, it would omit several and only print 1 – Charles Jr Dec 11 '17 at 06:01
  • Sorry, I still don't understand. Can you please update the Dartpad, create a new share linknand post it here and explain what result you'd expect instead? – Günter Zöchbauer Dec 11 '17 at 06:05
  • New DartPad Example: https://dartpad.dartlang.org/48149723e4bc4503a886becf130e1e03 I was expecting several nodes with "rank":2 together; not just 1. I got the "isValidKey" method from the documentation.. https://www.dartdocs.org/documentation/flutter/0.0.33-dev/dart-collection/SplayTreeMap/SplayTreeMap.from.html – Charles Jr Dec 11 '17 at 06:14
  • From the docs https://api.dartlang.org/stable/1.24.2/dart-collection/SplayTreeMap-class.html "Keys of the map are compared using the compare function passed in the constructor, both for ordering and for equality." The problem is that the compare function is also used for equality checks of the key. If to values are considered equal, then only one of the entries is retained. I guess you'll need to use a different collection type, but I don't have a good suggestion. Perhaps wrap the key and value together in an object (or a map) and use a list and the lists `sort()` to get the order you want. – Günter Zöchbauer Dec 11 '17 at 07:35
  • Lookups using for example `firstWhere()` will be less efficient though, but it depends on the number of entries and how often entries are looked up whether this is relevant. – Günter Zöchbauer Dec 11 '17 at 07:35