# Conditional column extraction

Let $$A$$ be the following matrix

A = {{1, 0, 9}, {5, 0, 6}, {4, 1, 9}, {7, 0, 11}, {8, 1, 2}}


and let $$B$$ be the matrix that comes from $$A$$ with

B = A[[All, {1, 3}]]


How can I implement the condition that $$B$$ is made only out of $$A$$'s rows that contain a zero?

(i.e. how can I get

B = {{1, 9}, {5, 6}, {7, 11}}


instead of

B = {{1, 9}, {5, 6}, {4, 9}, {7, 11}, {8, 2}}


? )

• Pick[A[[All,{1,3}]],Times@@@A,0] Jun 4, 2020 at 14:40

## 7 Answers

One way out of 100 ways I am sure :)

Select[A, MemberQ[#, 0] &][[All, {1, 3}]]


Or you could just delete the zeros

DeleteCases[Select[A, MemberQ[#, 0] &], 0, {2}]


If column 2 is binary, you can use

Pick[A[[All, {1, 3}]], A[[All, 2]], 0] (* or *)

Extract[A, Position[A[[All, 2]], 0], #[[{1, 3}]] &] (* or *)

A[[PositionIndex[A[[All, 2]]]@0, {1, 3}]]


to get

{{1, 9}, {5, 6}, {7, 11}}


In general, you can wrap column 2 with Unitize:

Pick[A[[All, {1, 3}]], Unitize @ A[[All, 2]], 0]

Extract[A, Position[Unitize @ A[[All, 2]], 0], #[[{1, 3}]] &]

A[[PositionIndex[Unitize[A[[All, 2]]]]@0, {1, 3}]]


I have a thing for Cases lately:


Cases[A,{PatternSequence[a_,0,b_]}:>{a,b}]

(* {{1,9},{5,6},{7,11}} *)



Nasser accurately points out that this is equivalent (& much more apt for code-golfing!):


Cases[A,{a_,0,b_}:>{a,b}]


• nice, yes cases is powerful. But in this case, you could just do Cases[A,{a_,0,b_}:>{a,b}] Ok, so we have like 10 ways shown so far. 90 more ways to do this is left :) Jun 5, 2020 at 1:23
• Thanks this is true. I'll update it! I like pattern-matching too much maybe hah! Jun 5, 2020 at 1:25
Query[All, If[#[[2]] == 0, #[[{1, 3}]], Nothing] &] @ A


{{1, 9}, {5, 6}, {7, 11}}

If[#2 == 0, {#1, #3}, Nothing] & @@@ list


{{1, 9}, {5, 6}, {7, 11}}

list = {{1, 0, 9}, {5, 0, 6}, {4, 1, 9}, {7, 0, 11}, {8, 1, 2}};


Position-related solutions

p = Position[list, 0]


{{1, 2}, {2, 2}, {4, 2}}

Using ReplaceAt (new in 13.1)

Cases[{_, _}] @ ReplaceAt[_ :> Nothing, p] @ list


{{1, 9}, {5, 6}, {7, 11}}

Using Delete

Cases[{_, _}] @ Delete[p] @ list


{{1, 9}, {5, 6}, {7, 11}}

Using Extract

Extract[list, p /. {a_, _} :> {a, {1, -1}}]


{{1, 9}, {5, 6}, {7, 11}}

list = {{1, 0, 9}, {5, 0, 6}, {4, 1, 9}, {7, 0, 11}, {8, 1, 2}};

SequenceCases[list, {{a_, 0, b_}} :> {a, b}]

DeleteCases[{_, Except[0], _}][list] // #[[All, {1, 3}]] &

list /. {a_, 0, b_} :> {a, b} // Select[Length@# == 2 &]


Result:

{{1, 9}, {5, 6}, {7, 11}}

list = {{1, 0, 9}, {5, 0, 6}, {4, 1, 9}, {7, 0, 11}, {8, 1, 2}};


Another way using AnyTrue, Pick and DeleteCases:

DeleteCases[Pick[#, AnyTrue[#, # == 0 &] & /@ #], 0, 2] &@list


Result:

{{1, 9}, {5, 6}, {7, 11}}

Or using SequenceReplace:

Cases[{_, _}]@SequenceReplace[list, {{a___, 0, b___}} :> {a, b}]


Result:

{{1, 9}, {5, 6}, {7, 11}}