6

I have a list of 4 elements {a, b, c, d}.

One of the elements has been assigned to a variable, say y, at some point in the program.

I am looking for a command that will delete the element of the list that is the same as y, BUT if two, three, or four of the elements are the same as y, I only want to delete one of the elements that are the same.

For example, say y=2 and list={1, 2, 4, 6}. I want the new list to be {1, 4, 6}.

For another example, say y=5 and list={3, 5, 5, 5}. I want the new list to be {3, 5, 5}.

corey979
  • 23,947
  • 7
  • 58
  • 101

6 Answers6

9

How about FirstPosition:

y = 2;
list = {1, 2, 4, 6};
pos = FirstPosition[list, y]

{2}

Drop[list, pos]

{1, 4, 6}

and

y = 5;
list = {3, 5, 5, 5};
pos = FirstPosition[list, y]

{2}

Drop[list, pos]

{3, 5, 5}

corey979
  • 23,947
  • 7
  • 58
  • 101
4

Offered for brevity and style:

drop[x_][h_[a___, x_, b___]] := h[a, b]

Tests:

{1, 2, 4, 6} // drop[2]

drop[5] /@ {{3, 5, 5, 5}, {5, 2, 1, 5}}

foo[m, a, t, h, e, m, a, t, i, c, a] // drop[m] // drop[t]
{1, 4, 6}

{{3, 5, 5}, {2, 1, 5}}

foo[a, h, e, m, a, t, i, c, a]

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
3

This also works although, I think, less efficiently than corey979's method.

removeFirst[x_?NumericQ, nums : {_?NumericQ ..}] := 
  Drop[nums, Catch[MapIndexed[If[#1 == x, Throw[#2], Nothing] &, nums]]]

Test cases

removeFirst[2, {1, 2, 4, 6}]

{1, 4, 6}

removeFirst[5, {3, 5, 5, 5}]

{3, 5, 5}

When 1st argument is not found in 2nd argument, returns 2nd argument.

removeFirst[2, {3, 4, 5, 6}]

{3, 4, 5, 6}

Handles case where 1st argument is integer and 2nd is list of reals.

removeFirst[2, Range[1., 3., .5]]

{1., 1.5, 2.5, 3.}

Handles symbolic numbers.

removeFirst[Pi, {E, Pi, E, Pi}]

{E, E, Pi}

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
3
DeleteCases[list, y, 1, 1]

{3, 5, 5}

where

list = {3, 5, 5, 5};
y = 5;
user1066
  • 17,923
  • 3
  • 31
  • 49
2

Since V 13.1 there is DeleteElements:

list = {1, 2, 4, 6};

DeleteElements[list, 1 -> {2}]

{1, 4, 6}

list = {3, 5, 5, 5};

DeleteElements[list, 1 -> {5}]

{3, 5, 5}

list = {2, 3, 5, 5, 5};

DeleteElements[list, {1, 2} -> {2, 5}]

{3, 5}

eldo
  • 67,911
  • 5
  • 60
  • 168
1
drop[x_][list_] := ReplacePart[list, FirstPosition[list, x] :> Sequence[]]
Ali Hashmi
  • 8,950
  • 4
  • 22
  • 42