8
$\begingroup$

I have a list of strings:

lis = {"a","1","b","2","c","3","a","d","4"}

and would like to get:

res = {"a","b","2","c","3","a","d","4"}

where each occurrence of "a" that is immediately followed by (a string representation of) an integer, that integer is deleted from the list. ToExpression followed by IntegerQ seems inefficient, would be grateful for thoughts.

$\endgroup$

6 Answers 6

8
$\begingroup$

SequenceReplace:

SequenceReplace[lis, {"a", _?(StringMatchQ[NumberString])} :> "a"]

 {"a", "b", "2", "c", "3", "a", "d", "4"}

Also

SequenceReplace[lis, {"a", _?(IntegerQ @* ToExpression)} :> "a"]

 {"a", "b", "2", "c", "3", "a", "d", "4"}

Split + ReplaceAll

Flatten[Split[lis, # == "a" &] /. {"a", _?(IntegerQ@*ToExpression) } :> "a"]

 {"a", "b", "2", "c", "3", "a", "d", "4"}

$\endgroup$
0
6
$\begingroup$

The following works for your example. But I am not sure that it will work for you if your example is not descriptive enough for some more general situation you have in mind.

lis = {"a", "1", "b", "2", "c", "3", "a", "d", "4"};
Flatten[Partition[lis, UpTo[2]] /. {"a", "1"} -> "a"]
{"a", "b", "2", "c", "3", "a", "d", "4"}
$\endgroup$
3
$\begingroup$
list = {"a", "1", "b", "2", "c", "3", "a", "3", "d", "4", "a", "9"};

Pre-define pattern for better readability

p = _?(StringMatchQ @ NumberString);

1.

With SequenceSplit (new in 11.3)

SequenceSplit[list, {"a", p} :> "a"]

{"a", {"b", "2", "c", "3"}, "a", {"d", "4"}, "a"}

Flatten[%]

{"a", "b", "2", "c", "3", "a", "d", "4", "a"}

2.

With SequencePosition (new in 10.1)

SequencePosition[list, {"a", p}] /. {_, a_} :> {a}

{{2}, {8}, {12}}

Delete[%] @ list

{"a", "b", "2", "c", "3", "a", "d", "4", "a"}

$\endgroup$
2
$\begingroup$

The input list is slightly modified to test for the case where only integers following "a" are removed.

lis = {"a", "1", "b", "2", "c", "3", "a", "1.4", "d", "4", "a", "2"};

Using PatternSequence and ReplaceRepeated:

lis //. {x___, PatternSequence["a", k_String], y___} /; 
   IntegerQ[ToExpression[k]] :> {x, "a", y}

or equivalently:

lis //. {x___, PatternSequence["a", _String?(IntegerQ@*ToExpression)],
    y___} :> {x, "a", y}

Using SequencePosition and Delete:

Delete[lis,  List /@ Last /@     SequencePosition[lis, {"a",
_?(IntegerQ@*ToExpression)}]  ]

Result

{"a", "b", "2", "c", "3", "a", "1.4", "d", "4", "a"}

$\endgroup$
2
$\begingroup$
list = {"a", "1", "b", "2", "c", "3", "a", "3", "d", "4", "a", "9"};

Grabbing the @eldo's list and using ReplaceRepeated:

list //. {r___, k : "a", n_?DigitQ, b___String, s___} :> {r, k, b, s}

(*{"a", "b", "2", "c", "3", "a", "d", "4", "a"}*)

Or using Delete and Position:

Delete[#, Function[p, p + 1]@Position[#, "a"]] &@list

(*{"a", "b", "2", "c", "3", "a", "d", "4", "a"}*)
$\endgroup$
1
$\begingroup$
list = {"a", "1", "b", "2", "c", "3", "a", "d", "4"};

Last /@ BlockMap[Replace[{"a", "1"} -> {"a"}], list, 2, 1]

{"a", "b", "2", "c", "3", "a", "d", "4"}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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