9
$\begingroup$

Here is a toy example to illustrate my problem. I have a list of 3-tuples and I want to delete elements from this list that satisfy a condition shown below.

tuples = Tuples[{-1, -2, 3}, {3}];
DeleteCases[tuples, _?((#[[1]] + 2 #[[2]] + #[[3]] == 0) &)]

This works perfectly. However, because each element of tuples has this form {a,b,c} and symbols a, b, c have problem-specific meanings attached to them, the code would become more readable if written as follows:

tuples = Tuples[{-1, -2, 3}, {3}];
DeleteCases[tuples, _?((a + 2*b + c == 0) &)]

The motivation is that a + 2*b + c == 0 is easier for a human to read and understand than (#[[1]] + 2 #[[2]] + #[[3]] == 0.

Question Is it possible to write this code using variables instead of slots?

$\endgroup$
3
  • 4
    $\begingroup$ If your problem has the same structure, you can use something like Pick[tuples,Unitize@Total[Transpose[tuples]*{1, 2, 1}], 1] $\endgroup$
    – Ben Izd
    May 3, 2022 at 7:43
  • 3
    $\begingroup$ @BenIzd Or Unitize[tuples . {1, 2, 1}] for the selection vector. $\endgroup$
    – Michael E2
    May 4, 2022 at 1:59
  • 2
    $\begingroup$ Related: pure-functions-with-lists-as-arguments $\endgroup$
    – expression
    May 5, 2022 at 6:08

4 Answers 4

12
$\begingroup$
tuples = {{1, 1, -3}, {1, 2, 3}};

(* Solution 1: *)
DeleteCases[tuples, {a_, b_, c_} /; a + 2 b + c == 0]
(* {{1, 2, 3}} *)

(* Solution 2: *)
DeleteCases[tuples, _?(({a, b, c} |-> a + 2 b + c == 0) @@ ## &)]
(* {{1, 2, 3}} *)

(* Solution 3: *)
test[{a_, b_, c_}] := a + 2 b + c == 0  
DeleteCases[tuples, _?test]
(* {{1, 2, 3}} *)
$\endgroup$
3
  • $\begingroup$ nice, I probably go for test function as I have many conditions. $\endgroup$
    – hana
    May 3, 2022 at 7:53
  • 2
    $\begingroup$ @hana And Select is a choice, too: test2[{a_, b_, c_}] := ! a + 2 b + c == 0; Select[tuples, test2] $\endgroup$
    – xzczd
    May 3, 2022 at 7:58
  • 2
    $\begingroup$ Or with Select[tuples, Not@*test] $\endgroup$
    – Ben Izd
    May 3, 2022 at 7:59
12
$\begingroup$

Pick could also be useful:

Pick[tuples, Function[{a, b, c}, a + 2 b + c == 0] @@@ tuples, False]
$\endgroup$
8
$\begingroup$
g[{a_, b_, c_}] := a + 2 b + c == 0

Using the operator form:

DeleteCases[x_ /; g[x]][tuples]
$\endgroup$
8
$\begingroup$

Perhaps (Thanks to comment/correction @BenIzd )

DeleteCases[tuples, _?(Apply@Function[{a, b, c}, a + 2 b + c == 0])]

is what you are looking for?

$\endgroup$
4
  • $\begingroup$ Yeah, I forgot that you can use Function like that. $\endgroup$
    – hana
    May 3, 2022 at 7:22
  • 2
    $\begingroup$ @hana ……This answer is incorrect. 2nd argument of DeleteCases is not a function. Try tuples = {{1, 1, -3}}; $\endgroup$
    – xzczd
    May 3, 2022 at 7:37
  • 2
    $\begingroup$ DeleteCases[tuples, _?(Apply@Function[{a, b, c}, a + 2 b + c == 0])] $\endgroup$
    – Ben Izd
    May 3, 2022 at 7:50
  • $\begingroup$ @xzczd I see, it doesn't remove anything. $\endgroup$
    – hana
    May 3, 2022 at 7:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.