Σύγχυση στη φυσική σειρά ταξινόμησης

Οι περισσότεροι διαχειριστές γραφικών αρχείων δεν ταξινομούν αυστηρά λεξικογραφικά, αλλά χρησιμοποιούν «φυσική» ταξινόμηση. Τα μπλοκ αριθμών στα ονόματα ερμηνεύονται ως αριθμοί—το μεγαλύτερο μπλοκ αριθμών κερδίζει, ακόμα κι αν το αντίθετο θα ίσχυε αλφαβητικά. Η ιδέα πίσω από τη φυσική ταξινόμηση: Αυτό που θέλουν συνήθως οι άνθρωποι είναι «9 πριν από το 10», «Κεφάλαιο 2 πριν από το Κεφάλαιο 10»—χωρίς να χρειάζεται να προσθέσουν αρχικά μηδενικά.


Τα ακόλουθα ζεύγη αρχείων ταξινομούνται φυσικά σε αύξουσα σειρά ως εξής:

  • build-9e2.log
  • build-950.log

Εκπληκτικό, αλλά εξηγήσιμο: Το πρώτο ψηφίο \(9\) είναι μικρότερο από το πρώτο μπλοκ ψηφίων \(950\) .

  • IMG_12113419_90.jpg
  • IMG_0554363070_90.jpg

Ο αριθμός \(12113419\) είναι μικρότερος από \(554363070\) (το πρώτο \(0\) αφαιρείται).

  • temp_0C.txt
  • temp_2C.txt
  • temp_-3C.txt
  • temp_10C.txt
  • temp_-12C.txt

Οι αριθμοί που συγκρίνονται είναι \(0\) , \(2\) , \(3\) , \(10\) , \(12\) – το «-» δεν θεωρείται μέρος του αριθμού.

Ακόμα και η λέξη «αλφαβητική» δεν είναι καθολικά σαφής: Η χρήση κεφαλαίων, τα διαλυτικά όπως ä (Γερμανικά) ή τα γράμματα πολλαπλών χαρακτήρων όπως ch (Τσεχικά) οδηγούν σε νόμιμες παραλλαγές. Η λέξη «καθαρά αλφαβητική» εξαρτάται επομένως από τα συμφραζόμενα. Η Εξερεύνηση των Windows υλοποιεί αυτό στη συνάρτηση StrCmpLogicalW . Ενώ ο πηγαίος κώδικάς της (shlwapi.dll) είναι ιδιόκτητος και όχι δημόσιος, υπάρχουν επανυλοποιήσεις, για παράδειγμα, από το ReactOS.:

{
    TRACE("%s, %s\n", wine_dbgstr_w(str), wine_dbgstr_w(comp));
 
    if (!str || !comp)
        return 0;
 
    while (*str)
    {
        if (!*comp)
            return 1;
        else if (*str >= '0' && *str <= '9')
        {
            int str_value, comp_value;
 
            if (*comp < '0' || *comp > '9')
                return -1;
 
            /* Compare the numbers */
            StrToIntExW(str, 0, &str_value);
            StrToIntExW(comp, 0, &comp_value);
 
            if (str_value < comp_value)
                return -1;
            else if (str_value > comp_value)
                return 1;
 
            /* Skip */
            while (*str >= '0' && *str <= '9') str++;
            while (*comp >= '0' && *comp <= '9') comp++;
        }
        else if (*comp >= '0' && *comp <= '9')
            return 1;
        else
        {
            int diff = ChrCmpIW(*str, *comp);
            if (diff > 0)
                return 1;
            else if (diff < 0)
                return -1;
 
            str++;
            comp++;
        }
    }
 
    if (*comp)
      return -1;
 
    return 0;
}

Το Google Drive, το OneDrive, το KDE και άλλα εμφανίζουν παρόμοια συμπεριφορά ταξινόμησης. Εργαλεία CLI όπως ls και find Ωστόσο, ταξινομούνται διαφορετικά από τους διαχειριστές αρχείων GUI. Η σημασιολογία βρίσκεται στα ονόματα των αρχείων, όχι στο API. Αν θέλετε αποτελέσματα χωρίς εκπλήξεις, ορίστε συμβάσεις: συνεπή διαχωριστικά, γεμισμένους αριθμούς και σαφή χειρισμό των μονάδων. Στη συνέχεια, το "αλφαβητικό" γίνεται ξανά προβλέψιμο.

Πίσω