4
$\begingroup$

I have to drop the rows of a table only when the element in the first coloumn of the row satisfies multiple condition.

The table:

tab = Table[{i, i^2}, {i, 1, 10}]
{{1, 1}, {2, 4}, {3, 9}, {4, 16}, {5, 25}, {6, 36}, {7, 49}, {8, 64}, {9, 81}, {10, 100}}

What i tried:

dim = Dimensions[tab][[1]]
For[i = dim, i > 0, i--,
 If[tab[[i, 1]] > 8||tab[[i, 1]] < 2,
  tab = Drop[tab, i, None]]]

What it does:

tab
 {}

What i expect

tab
{{2, 4}, {3, 9}, {4, 16}, {5, 25}, {6, 36}, {7, 49}, {8, 64}}
$\endgroup$
  • 5
    $\begingroup$ Try Select[Table[{i, i^2}, {i, 1, 10}], First[#] <= 8 &]. $\endgroup$ – J. M.'s technical difficulties Jun 5 at 18:36
  • 2
    $\begingroup$ Although, using For is generally discouraged; if you are going to use it in this instance, learn the syntax for Drop. Note that tab = Drop[tab, i] drops multiple rows, i.e., the first i rows. You want tab = Drop[tab, {i}] which will just drop row i. $\endgroup$ – Bob Hanlon Jun 5 at 19:11
7
$\begingroup$
DeleteCases[tab, _?(#[[1]] < 2 || #[[1]] > 8 &)]
| improve this answer | |
$\endgroup$
6
$\begingroup$

Select the wanted:

f1 = Function[i, {i, i^2}]
tab = Table[f1[i], {i, 1, 10}]
keep = Function[i, 9 > i > 1] (* the selection predicate *)
Select[tab, keep@*First]

Or, don't create the unwanted:

f2 = Function[i, If[keep[i], {i, i^2}, Nothing]]
Table[f2[i], {i, 10}]
| improve this answer | |
$\endgroup$
4
$\begingroup$

You could also use Except with Cases...

Cases[tab,Except[{a_,b_}/;a>8||a<2]]

{{2,4},{3,9},{4,16},{5,25},{6,36},{7,49},{8,64}}

| improve this answer | |
$\endgroup$
1
$\begingroup$

The OP wants to drop the rows of a table only when the values in the first column satisfy multiple conditions, specifically (as an example) when the values in the first column are less than 2 and greater than 8.

Two powerful functions that may be useful here are Select and Pick

Select

As J. M.'s technical difficulties neatly showed in a comment, and in an astute criticism of my original post, Select may be used in the following manner to solve the problem:

Select[tab, 2 <= First[#] <= 8 &]

{{2, 4}, {3, 9}, {4, 16}, {5, 25}, {6, 36}, {7, 49}, {8, 64}}

Alternatively (again due to J. M.'s technical difficulties), Between may be used to avoid slots completely:

Select[tab, Between[{2, 8}] @* First]

{{2, 4}, {3, 9}, {4, 16}, {5, 25}, {6, 36}, {7, 49}, {8, 64}}

Two other variants with Select (from original post):

Select[tab, First[#]>=2 && First[#] <= 8 &]

and:

Select[tab, !(First[#]<2 || First[#] > 8) &]

Pick

Maybe something like the following:

Pick[tab,Between[{2, 8}]/@tab[[All,1]]]

{{2, 4}, {3, 9}, {4, 16}, {5, 25}, {6, 36}, {7, 49}, {8, 64}}

or (original answer):

Pick[tab,#>8 || #<2&/@tab[[All,1]],False]

Comment

As the above is not original and might even be considered obvious, I have made this answer a Community wiki. Feel free to edit/append/delete as required. IMO we need to be careful that the obvious answer, and not just the more innovative and creative solutions, is included in posts such as this, for the benefit of future visitors to the site

$\endgroup$
  • 2
    $\begingroup$ (+1 of course.) Whenever possible, I prefer to write selection conditions of this kind in interval format: Select[tab, 2 <= First[#] <= 8 &]. In particular, using Between[] allows for writing a slot-free version: Select[tab, Between[{2, 8}] @* First]. $\endgroup$ – J. M.'s technical difficulties Jun 6 at 10:14

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