Sort a list in Dart not the same as sorted list in Swift

263

true/false is different from 0/1 here.

Dart sort checks 3 different things.

In a comparison between A and B, we have 3 possibilities:

  • The callback returns 0. In which case A and B are equal
  • The callback returns a number > 0. It means that A is placed after B
  • The callback returns a number < 0. In which case A is placed before B.
Share:
263
iKK
Author by

iKK

Updated on December 08, 2022

Comments

  • iKK
    iKK over 1 year

    I have successfully implemented a sorting algorithm in Swift for iOS. (see code below).

    Now, I would like to implement the same algo in Dart for Flutter.

    And I had to realise that my trial (see below) does not do the same as the Swift code. Why ????

    Can anybody explain the difference between Swift's sorted function and Dart's sort function ? Why is my below code-snippets not doing the same in Swift and Dart ???

    Here is the Swift code:

    return stationItems.sorted {
        let nameA = $0.name!
            .replacingOccurrences(of: ",", with: "", options: .literal, range: nil)
            .replacingOccurrences(of: "ä", with: "a", options: .literal, range: nil)
            .replacingOccurrences(of: "ö", with: "o", options: .literal, range: nil)
            .replacingOccurrences(of: "ü", with: "u", options: .literal, range: nil)
            .lowercased()
        let nameB = $1.name!
            .replacingOccurrences(of: ",", with: "", options: .literal, range: nil)
            .replacingOccurrences(of: "ä", with: "a", options: .literal, range: nil)
            .replacingOccurrences(of: "ö", with: "o", options: .literal, range: nil)
            .replacingOccurrences(of: "ü", with: "u", options: .literal, range: nil)
            .lowercased()
        let searchTermy = searchTerm
            .replacingOccurrences(of: ",", with: "", options: .literal, range: nil)
            .replacingOccurrences(of: "ä", with: "a", options: .literal, range: nil)
            .replacingOccurrences(of: "ö", with: "o", options: .literal, range: nil)
            .replacingOccurrences(of: "ü", with: "u", options: .literal, range: nil)
            .lowercased()
    
        if nameA == searchTermy && nameB != searchTermy {
            return true
        } else if nameA.hasPrefix(searchTermy) && !nameB.hasPrefix(searchTermy)  {
            return true
        } else if nameA.contains(searchTermy) && !nameB.contains(searchTermy) {
            return true
        } else {
            let n = searchTermy.count
            for i in 0..<searchTermy.count {
                if nameA.hasPrefix(String(searchTermy[..<(n-i)])) && !nameB.hasPrefix(String(searchTermy[..<(n-i)])) {
                    return true
                } else {
                    return false
                }
            }
            return false
        }
    }
    

    Here is the Dart code:

    return stationList.sort((a, b) {
       var nameA = a.stopName
          .replaceAll(RegExp(','), '')
          .replaceAll(RegExp('ä'), 'a')
          .replaceAll(RegExp('ö'), 'o')
          .replaceAll(RegExp('ü'), 'u')
          .toLowerCase();
       var nameB = b.stopName
          .replaceAll(RegExp(','), '')
          .replaceAll(RegExp('ä'), 'a')
          .replaceAll(RegExp('ö'), 'o')
          .replaceAll(RegExp('ü'), 'u')
          .toLowerCase();
       var searchTermy = stationName
          .replaceAll(RegExp(','), '')
          .replaceAll(RegExp('ä'), 'a')
          .replaceAll(RegExp('ö'), 'o')
          .replaceAll(RegExp('ü'), 'u')
          .toLowerCase();
       if ((nameA == searchTermy) && (nameB != searchTermy)) {
          return 1;
       } else if (nameA.startsWith(searchTermy) && !nameB.startsWith(searchTermy)) {
          return 1;
       } else if (nameA.contains(searchTermy) && !nameB.contains(searchTermy)) {
          return 1;
       } else {
          var n = searchTermy.length;
          for (int i = 0; i < searchTermy.length; i++) {
            if (nameA.startsWith(searchTermy.substring(0, (n - i))) && !nameB.startsWith(searchTermy.substring(0, (n - i)))) {
              return 1;
           } else {
              return 0;
           }
         }
         return 0;
       }
    });
    
    • Martin R
      Martin R about 5 years
      A concrete example with input and expected/actual output would be helpful.
  • iKK
    iKK about 5 years
    Thank you, Rémi. I saw that too. But I guess, what I do not understand is why my Dart-List gets changed even if I return 0. Or in other words, why is the following muting the list, instead of leaving it as it is: stationList.sort((a, b) { return 0; });
  • Rémi Rousselet
    Rémi Rousselet about 5 years
    That's just how sort works. It doesn't create a new list, it sorts the existing one. To begin with, sort returns nothing.
  • iKK
    iKK about 5 years
    Ah, it starts making sense.... The true/false in Swift means that iterating through the list - the elements ($0 and $1) for a given iterating-moment are either mutated in position (if true: A is placed before B) or kept in position (if false).
  • iKK
    iKK about 5 years
    In Dart, the sort works differently and iterating through the list cannot have the same two-fold decision as in Swift's sorted but rather requires a triple-state implementation as you described above. true must translate in callback-return < 0 I guess - and false must either be 0 or > 0 or < 0 depending on the elements at a given time in the iteration. Does this make sense ?