Sorting a sparse matrix so that non-empty rows place on top

I have a $$n$$ by $$2$$ matrix that has binary values(0,1) as its entry. For example

m={{1,Null},{Null,0},{Null,Null},{0,0},{1,0},{0,1}}

I want it to be sorted according to a simple rule: 1) place non-empty ones at the top and empty ones at the bottom; 2) if a row has only one non-empty value, the row that has a non-empty value in column 2 places before the row that has a non-empty value in column 1. For example, {Null,0} should be placed before {1,Null}.

So, the final list I want to have should look like:

m_sorted={{0,0},{1,0},{0,1},{Null,0},{1,Null},{Null,Null}}.

How can I do this type of sorting?

• "{Null, 0} should be placed before {1, Null}" - and yet in your sorted list, you have {1, Null}, {Null, 0}. Do make up your mind. Apr 26, 2020 at 14:07
• @J.M. Oh, sorry:) I've fixed it. Apr 26, 2020 at 14:08
• Tip not directly directed at the problem here: if $n$ tends to be large in your use cases, then using Null is going to slow things down compared to using another integer, say, -1. The reason is that Mathematica can "pack" arrays that only contain one type (typically ints or floats). Using Null prevents that. Apr 26, 2020 at 20:28

Not very elegant but should do the trick:

• select the pairs of integers without reordering
• select the pairs of one integer and one Null and reorder by Null first
• select the pairs of Nulls
• join all that

and enjoy.

   process[m_] := Block[{a, b, c},
a = Select[m, IntegerQ@Total@# &];
b = SortBy[Last]@Select[m, Count[#, Null] == 1 &];
c = Select[m, # == {Null, Null} &];
Flatten[Join[{a, b, c}], 1]]
process[m]

(* {{0, 0}, {1, 0}, {0, 1}, {Null, 0}, {1, Null}, {Null, Null}} *)

• Thank you for the accept but, especially if you are looking for performances, Roman and kglr's answer are probably better. Apr 27, 2020 at 19:55
SortBy[m, {Count[#, Null], #[[2]]} &]

(*    {{0, 0}, {1, 0}, {0, 1}, {Null, 0}, {1, Null}, {Null, Null}}    *)

SortBy[{Count[Null], Last}] @ m

{{0, 0}, {1, 0}, {0, 1}, {Null, 0}, {1, Null}, {Null, Null}}


Also

m[[Ordering[Through[{Count[Null], Last}@#] & /@ m]]]

{{0, 0}, {1, 0}, {0, 1}, {Null, 0}, {1, Null}, {Null, Null}}