# How can the lowest non-zero value in a nested list be found and its position in the sublist returned?

In the example code below we have a list of triples that produce one or more sublists with at least one zero value. How can the positions of the lowest non zero value in each sublist be returned where that condition applies, and identify those sublists whose lowest value is zero so that the overall positions of the non-zero values can be obtained, and not lose their positions in the overall list?

 In[1]= myList=Partition[RandomSample[Range[0, 8], 9], 3]
Out[1]= {{3, 1, 8}, {5, 0, 2}, {7, 6, 4}}


What I would like to get returned is something like this: {2,z,3} for the above list. Thanks for the help!

-
"its" - possessive, not "it's" (title) – alancalvitti Jul 17 '12 at 4:35
+1 for the english lesson ;) – R Hall Jul 18 '12 at 0:17

You could also use Position instead of Ordering so that the positions of all the lowest values in each sublist can be found:

Clear@f
f[l_List] /; Min@l != 0 := Flatten@Position[#, Min@#] &@l
f[_] := z


For example:

myList = {{2, 0, 5, 0}, {1, 4, 8, 1}, {7, 2, 6, 3}};
f /@ myList
(* {z, {1, 4}, {2}} *)


A simpler way of writing the same would be:

Clear@g
g[l_List] := With[{m = Min@#}, If[m === 0, z, Flatten@Position[#, m]]] &@l

-
Very elegant solution! Thank you! – R Hall Jul 17 '12 at 3:00

An answer in the form of a function. Using Part and ReplaceAll help make the function clearer in my opinion. Read from the inside out. That's how the function was built. First I got the Map to work. Then wrapped it with a ReplaceAll (/.). Then extracted the desired column.

process[lis_] :=
Part[
ReplaceAll[
Map[{Ordering[#, 1][[1]], Min[#]} & , lis],
{_, 0} -> {"z", 0}
],(* ReplaceAll *)
All, 1
] (* Part *)


and then

test = {{3, 1, 8}, {5, 0, 2}, {7, 6, 4}};
process[test]


gives

{2, "z", 3}

-
f[l_List] := With[{minPos = First@Ordering[l, 1]}, minPos /; l[[minPos]] =!= 0];
f[_] := $Failed  You use it like f /@ myList But what you ask isn't straightforward if what you say you want is what you want: that is, the overall minimmu of the non-zero values Ordering[#, 1] & /@ (myList /. {0 -> Infinity})  Also, if you know that there are never negative values (if there's a zero, it will always be the minimum), you can discard those lists first f[{___, 0, ___}] :=$Failed
f[l_] := First@Ordering[l, 1]

-
I'm unable to produce the example solution, but certainly have learned some new tricks here. Thanks! – R Hall Jul 17 '12 at 3:03
@RHall, did you remember to ClearAll@f after running RMs solution, before trying mine? – Rojo Jul 17 '12 at 3:55
I ran yours first on a clean kernel. Certainly a good solution. Thanks very much! – R Hall Jul 17 '12 at 11:25