# Array sorting of file paths

**URL:** <https://discourse.processing.org/t/array-sorting-of-file-paths/33096>\
**Category:** Coding Questions\
**Created:** [October 26, 2021, 4:13pm UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096 "2021-10-26T16:13:11Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![garrettlynch](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/garrettlynch/32/19853_2.png) [@garrettlynch](https://discourse.processing.org/u/garrettlynch)\
**Post date:** [October 26, 2021, 4:13pm UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/1 "2021-10-26T16:13:12Z")

</div>

I am creating an array from a directory of images using listFiles() and then sorting them like so.

```auto
  images = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().toLowerCase().endsWith(".png");
            }
        });
   
   Arrays.sort(images);

```

However, the images in my directory don’t use leading zeros so look like this.

images/16/0.png  
images/16/1.png  
images/16/2.png  
…  
images/16/100.png  
images/16/101.png

As I pull each one out in order I get 0.png, 1.png, 100.png etc. - not what I want, I want 0.png, 1.png, 2.png etc. Is there something that can be used in sort to resolve this or an alternative way of sorting that will correct this?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [October 26, 2021, 4:20pm UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/2 "2021-10-26T16:20:13Z")

</div>

Back up your images

Write a processing code to rename the files in the folder

Sorry, I can’t run your code.

Can you post our entire code?

What imports do you use please?

---

<div class="post-metadata">

**Author:** ![BrendanL](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/brendanl/32/14076_2.png) [@BrendanL](https://discourse.processing.org/u/BrendanL)\
**Post date:** [October 27, 2021, 4:26pm UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/3 "2021-10-27T16:26:52Z")

</div>

This is a common problem that has no library solution I’ve ever encountered. I’ve always seen it solved by writing a custom sort function that parses the numbers out of the file names and uses them to determine the order.

---

<div class="post-metadata">

**Author:** ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)\
**Post date:** [October 27, 2021, 4:50pm UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/4 "2021-10-27T16:50:03Z")

</div>

You can also use one of the many free utility tools that let you rename files in batch.  
You could easily add leading zeros to your number and use classic array sort to sort your files.

---

<div class="post-metadata">

**Author:** ![MiguelSanches](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/miguelsanches/32/11172_2.png) [@MiguelSanches](https://discourse.processing.org/u/MiguelSanches)\
**Post date:** [October 28, 2021, 11:58am UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/5 "2021-10-28T11:58:33Z")

</div>

My approach to this would be to first order each String image filepath by length and then by its natural order. So, first you have all images/16/1.png … to images/16/9.png and so on.  
In java 8 or above this could be accomplished using:

```auto
Arrays.sort(images,Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()));

```

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/4/4cdbad47edd0a38f835240e114d489c2ba7d150e.png)

But I don’t know with which version of java you are working on. If it is below 8 then you have to do a customized function but the logic might be the same

Hope it helps!

---

<div class="post-metadata">

**Author:** ![garrettlynch](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/garrettlynch/32/19853_2.png) [@garrettlynch](https://discourse.processing.org/u/garrettlynch)\
**Post date:** [October 28, 2021, 5:28pm UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/6 "2021-10-28T17:28:22Z")

</div>

Using Java 11 in Processing 4 so your comparator solution is the same one I’ve hit on. Your version here won’t work for me as is because you are using a String[] and I’m using a File[], which I didn’t specify, so it chokes on `String::length`. I thought something like `str(File)::length` but no - unclear how to pull out each file and convert is to a string so I can use `length`.

For everyone else telling me to rename files, this isn’t an option for me. I won’t be in control of the folder being traversed but apart from that leading zeros is not a great solution as it sets a count upper limit for the file name i.e. they have to stop at say 9999.png etc.

```auto
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

String imagespath;
File[] images;

void setup()
{
  size(480, 672);

  // Path to images folder
  imagespath = sketchPath() + "/images/";
  File dir = new File(imagespath);

  // Get an array of all folders inside images folder
  File[] folders = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory();
            }
        });

  // Randomly select a folder
  int folderlength = folders.length;
  int i = int(random(folderlength));
  dir = new File(folders[i].getAbsolutePath() + "/");

  // Get an array of all png images
  images = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().toLowerCase().endsWith(".png");
            }
        });
   
   //Arrays.sort(images);
   //print(Arrays.toString(images) + "\n\n"); 

Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder()));
print(Arrays.toString(images)); 
   exit();
}

```

---

<div class="post-metadata">

**Author:** ![MiguelSanches](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/miguelsanches/32/11172_2.png) [@MiguelSanches](https://discourse.processing.org/u/MiguelSanches)\
**Post date:** [October 29, 2021, 8:19am UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/7 "2021-10-29T08:19:52Z")

</div>

Hi @garrettlynch

According to Oracle java documentation, File has a `toString()` method, which returns the pathname string of this abstract pathname. Maybe you need to invoke this method instead of str(). I tried running your code but since I don’t have the structure or images I can’t test it.  
Hope it helps!

Check also these links:

> **Links**
>
> [java - How to sort file names in ascending order? - Stack Overflow](https://stackoverflow.com/questions/16898029/how-to-sort-file-names-in-ascending-order)  
> [NameFileComparator (Apache Commons IO 2.11.0 API)](https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/comparator/NameFileComparator.html)

If I have the time I will try to create random images to test your code again. But I highly doubt that this is something that cannot be solved with all Java IO File and NIO classes.

---

<div class="post-metadata">

**Author:** ![MiguelSanches](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/miguelsanches/32/11172_2.png) [@MiguelSanches](https://discourse.processing.org/u/MiguelSanches)\
**Post date:** [October 29, 2021, 1:53pm UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/8 "2021-10-29T13:53:39Z")

</div>

Just test the code snippet below after getting the images File[]

```auto
String arr[] = new String[images.length];
   for(int j = 0; j<images.length; j++){
     arr[j] = images[j].toString();
   }
 // printArray(arr);

Arrays.sort(arr, Comparator.comparingInt(String::length).thenComparing(Comparator.naturalOrder())));
printArray(arr); 
   

```

---

<div class="post-metadata">

**Author:** ![garrettlynch](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/garrettlynch/32/19853_2.png) [@garrettlynch](https://discourse.processing.org/u/garrettlynch)\
**Post date:** [November 1, 2021, 10:17am UTC](https://discourse.processing.org/t/array-sorting-of-file-paths/33096/9 "2021-11-01T10:17:33Z")

</div>

Yes the natural sorting works (minus the extra typo bracket at the end of `Arrays.sort()`). I’m looking into the `toString()` method you mentioned in File. Would be nice/tidier to keep it as a `File[]` and just use the strings temporarily while sorting but failing that this will be my fall back solution. Many thanks for your help!
