# Sorting Array With Nulls At Bottom?

Hello Everyone. I need to know how to reorganize an array so that Null indexes appear at the bottom.

I know you can use the ‘Array.sort’ method to sort numbers. But I have an array of GameObjects. I can’t seem to find any way to do this.

Thank you very much a really appreciate the time!

I don’t believe you can, at least on straight gameobjects. You can just do it manually though.

``````        // before
for (int i = 0; i < go_array.Length; i++) { Debug.Log(go_array[i]); }

// create a temp array
GameObject[] temp_array = new GameObject[go_array.Length];
int count = 0;

// fill it
for (int i = 0; i < go_array.Length; i++)
{
if(go_array[i]!=null)
{
temp_array[count] = go_array[i];
count++;
}
}

// assign it
go_array = temp_array;

// after
for (int i = 0; i < go_array.Length; i++) { Debug.Log(go_array[i]); }
``````
1 Like

If only this were C++, I’d direct you to the std.partition() function.

I don’t know of a similar utility function in .NET, so you might just need to write your own. Fortunately, it’s not too hard.

A simple way to do it is to work from the front, looking for null elements to move to the back partition, and simultaneously work from the back, looking for non-null elements to move to the front partition. At each step, you simply swap the earliest null element with the latest non-null element. Keep doing this until the two positions meet somewhere in the middle. At that point, you know that all the elements before the meeting point are non-null, and all elements after it are null.

(Note that this is an unstable partition, that is, the relative ordering of the non-null elements may change.)

Here’s a hasty and untested attempt to implement it:

``````void PartitionNullsAtEnd(GameObject[] objects)
{
if (objects.Length <= 1) return; // Nothing to partition.
int i = 0; // Index starting at front.
int j = objects.Length - 1; // Index starting at back.
do
{
// Skip over all non-null elements at the front.
while (objects[i] != null)
{
if (++i >= j) return; // If indices meet, we're done.
}
// Skip over all null element at the back.
while (objects[j] == null)
{
if (--j <= i) return; // If indices meet, we're done.
}
// Swap the non-null and null elements with each other.
objects[i] = objects[j];
objects[j] = null;
// Move the indices one element toward the middle.
++i;
--j;
} while (i < j); // Keep going until the indices meet.
}
``````
1 Like

Just write a comparison delegate.

``````int CompareGameObjects(GameObject go1, GameObject go2)
{
if(go1 == null || go2 == null)
return 1; // move it up the array (this might actually need to be -1, I forget)

return 0; // keep it in the same spot
}

// then later:
GameObject[] gameObjects; // populate it however you have it

Array.Sort(gameObjects, CompareGameObjects);
``````
3 Likes

You guys are all awesome. Thank you very much. I was able to fix my problem

I’m not sure that particular comparison is going to get the job done. 0 doesn’t really mean to not move the element. It just means that the two elements that the sorting algorithm is curious about are equivalent as far as the comparison is concerned. Which should also be true for two nulls. And if only one of the two elements is null, then whether to return a positive or negative 1 depends on which of the two is null.

I think this would work, and is a lot shorter than my earlier code, but also less performant, if that matters:

``````Array.Sort(gameObjects, (GameObject lhs, GameObject rhs) =>
{
if ((lhs == null) == (rhs == null)) return 0; // If they're either both null or both not null, they're equal.
return lhs == null ? 1 : -1; // If the first is null, it's greater than rhs, else it's less.
});
``````

With Linq its really straightforward

``````using System.Linq;
...
public GameObject[] objects;
...
objects = objects.OrderBy(element=> element == null).ToArray();
``````

This is an odd one. Are you sure you want to do this? Why do you want to do this? Do you really want a sort? There is typically no value to copying the same null references around.

One approach would be to step through every item in the collection, closing gaps as you go. Then assign the rest of the items to null. Its not technically a sort, but it will do the job. And its probably faster then using LINQ or Array.Sort. Like so (slight abuse of the while loop, be careful of potential infinite loops):

``````int index = 0;
int i = 0;
while (index < items.Length){
items[i] = items[index];
index++;
if (items[i] !=null) i++;
}
while (i < items.Length){
items[i] = null;
i++;
}
``````

However in most cases a much better solution would be to simply use a dynamic size collection, like a List, and remove the null references altogether. You can do this in a single line with a List. RemoveAll is a linear search, so its probably just as efficient as anything else suggested here. Plus you don’t have the

``````items.RemoveAll(x => x == null);
``````

(Also note that with GameObjects you will have to be aware of Unity’s FakeNull.)

That while loop was bothering me. Here is the more elegant for loop.

``````int i = 0;
for (int index = 0; index < items.Length; index++){
items[i] = items[index];
if(items[i] != null) I++;
}
for (; i < items.Length; i++) {
items[i] = null;
}
``````

Still reccomend not doing this.