How to sort values (numbers) in all lines of a file without sorting the lines in file?

How to sort values (numbers) in all lines of a file without sorting the lines in file?

24
Basic UserBasic User
24

    Jul 02, 2020#1

    Hi,

    I need a simple sort values per line script.

    For example:

    Code: Select all

    31 34 26 01 02 28
    13 17 01 28 26 30
    20 14 04 05 30 16
    Should result in:

    Code: Select all

    01 02 26 28 31 34
    01 13 17 26 28 30
    04 05 14 16 20 30
    Thanks

    6,605547
    Grand MasterGrand Master
    6,605547

      Jul 02, 2020#2

      Is the delimiter always a space character?

      Are the space delimited values always two digit numbers or can the number of digits vary or are there even other strings?

      What is the typical file size of the file on which the values in the lines should be sorted?
      Best regards from an UC/UE/UES for Windows user from Austria

      24
      Basic UserBasic User
      24

        Jul 02, 2020#3

        The end is the always [CR][LF]. Yes, always a space.

        Yes, always two digits (from 01 to 41).

        They are string anyway (not numerical).

        Size isn't that big, around 200 KB.

        I had this before, but it is not working.

        Code: Select all

        if (UltraEdit.document.length > 0)
        {
           // Define the environment for the script.
           UltraEdit.insertMode();
           if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
           else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
           UltraEdit.activeDocument.hexOff();
           // Select all and load the file contents into an array of lines.
           UltraEdit.activeDocument.selectAll();
           if (UltraEdit.activeDocument.isSel())
           {
              var asLines = UltraEdit.activeDocument.selection.split("\r\n");
              // Sort the space separated numbers within every line.
              for (var nLineNum = 0; nLineNum < asLines.length; nLineNum++)
              {
                 if (!asLines[nLineNum].length) continue;  // Ignore empty lines.
                 // Split the line up into an array of number strings.
                 var asNumbers = asLines[nLineNum].split(" ");
                 // Run a simple string sort based on ASCII table.
                 asNumbers.sort();
                 // Remove duplicate numbers.
                 var nNumberIndex = 0;
                 while (nNumberIndex < (asNumbers.length -1))
                 {
                    // Is current number string equal next number string in sorted array?
                    if (asNumbers[nNumberIndex] == asNumbers[nNumberIndex+1])
                    {
                       asNumbers.splice(nNumberIndex+1,1);  // Yes, remove next string.
                    }
                    else
                    {
                       nNumberIndex++;  // No, continue with next number string.
                    }
                 }
                 // Rebuild the line with the sorted numbers with duplicates removed.
                 asLines[nLineNum] = asNumbers.join(" ");
              }
              // Remove last string from array if it is an empty string
              // because the file ends with a line termination.
              if(asLines[asLines.length-1] == "") asLines.pop();
              asLines.sort();   // Sort the lines alphabetically.
              asLines.push(""); // Append an empty string to terminate finally last line.
        
              // Replace the still existing selection by resorted lines.
              // The write command below is fast for some lines (50 or 200)
              // but very slow for larger blocks with 5000 or more lines.
              // UltraEdit.activeDocument.write(asLines.join("\r\n"));
              // The alternate version using paste via a user clipboard is always
              // very fast even for larger blocks with thousands of lines.
              UltraEdit.selectClipboard(9);
              UltraEdit.clipboardContent = asLines.join("\r\n");
              UltraEdit.activeDocument.paste();
              UltraEdit.clearClipboard();
              UltraEdit.selectClipboard(0);
           }
        }

        6,605547
        Grand MasterGrand Master
        6,605547

          Jul 02, 2020#4

          The script works perfect. It sorts the two digit numbers using a simple alphabetic string sort and removes next duplicate numbers on a line.  Finally after processing the values of each line it sorts also the lines itself alphabetically. The script works for your example with taking into account that the lines itself are sorted also by the script.

          The following block should be removed from the script if sorting of lines is not wanted at all.

          Code: Select all

                // Remove last string from array if it is an empty string
                // because the file ends with a line termination.
                if(asLines[asLines.length-1] == "") asLines.pop();
                asLines.sort();   // Sort the lines alphabetically.
                asLines.push(""); // Append an empty string to terminate finally last line.
          What do you mean with "not working"?

          "Not working" is no error description.

          Do you see an error output in output window on execution of the script?

          An alphabetic string sort for sorting in ascending order the two digit numbers would not be possible if the number of digits varies between the numbers which is the reason for my first question in my first post. A simple split on a single space would not be possible if other characters or a series of spaces can be between the numbers which is the reason for my second question in first post. Doing everything in memory of JavaScript core engine would not be possible if the file size is too large which is the reason for my third question in my first post.
          Best regards from an UC/UE/UES for Windows user from Austria

          24
          Basic UserBasic User
          24

            Jul 02, 2020#5

            Mofi wrote:
            Jul 02, 2020
            What do you mean with "not working"?

            "Not working" is no error description.

            Do you see an error output in output window on execution of the script?
            Hi,

            It doesn't work as the result is:

            Code: Select all

            01 01
            02 01
            04 01
            05 01
            07 01
            08 01
            There isn't any duplicate too.

            Gradius

            6,605547
            Grand MasterGrand Master
            6,605547

              Jul 03, 2020#6

              The output for

              Code: Select all

              31 34 26 01 02 28
              13 17 01 28 26 30
              20 14 04 05 30 16
              is

              Code: Select all

              01 02 26 28 31 34
              01 13 17 26 28 30
              04 05 14 16 20 30
              The output for

              Code: Select all

              01 01
              02 01
              04 01
              05 01
              07 01
              08 01
              is

              Code: Select all

              01
              01 02
              01 04
              01 05
              01 07
              01 08
              That are two times the results expected by me according to code and the comments in code. So I still don't know what is not working.

              Which version of UltraEdit do you use on which operating system?
              Best regards from an UC/UE/UES for Windows user from Austria

              24
              Basic UserBasic User
              24

                Jul 04, 2020#7

                Hi,

                No no.

                The input is the very same:

                Code: Select all

                31 34 26 01 02 28
                13 17 01 28 26 30
                20 14 04 05 30 16
                The output is pretty wrong.

                Version is 26.20.0.68

                6,605547
                Grand MasterGrand Master
                6,605547

                  Jul 04, 2020#8

                  I restored UltraEdit for Windows v26.20.0.68 and executed the script SortNumbersAndLines_v1.js on file SortNumbersAndLines_Input.txt which modified the file contents as stored next manually by me into file SortNumbersAndLines_Result.txt. So I could not reproduce that the script is not working as designed which means sorting the two digit numbers on a line, removing duplicate numbers on a line, and last sorting alphabetically the lines.

                  I enhanced the script to support now also text files with UNIX or MAC line terminators and support other delimiters between the numbers like no-break space, horizontal tab or whatever is used as delimiter. The enhanced script SortNumbersAndLines_v2.js outputs also three informational lines to output window and shows the output window at end of execution if a file is opened in UltraEdit on running the script which is not empty.
                  SortNumbersAndLines.zip (2.72 KiB)   0
                  The ZIP file contains the four files described in the post.
                  Best regards from an UC/UE/UES for Windows user from Austria

                  24
                  Basic UserBasic User
                  24

                    Jul 04, 2020#9

                    I just didn't needed to have the whole thing sorted out, so I comment this one:

                    Code: Select all

                    // asLines.sort();   // Sort the lines alphabetically.
                    Great job as usual!   Thanks a lot.

                    6,605547
                    Grand MasterGrand Master
                    6,605547

                      Jul 04, 2020#10

                      I wrote already in my second post which lines to remove to prevent sorting the lines in file. The script contains also comments explaining the code. You would have saved us a lot of time on just reading what I wrote in my posts and the comments in script and making in your posts more clear what you want.

                      However, important is only that you have now the script you want.
                      Best regards from an UC/UE/UES for Windows user from Austria