10
$\begingroup$

I have a list of strings $\{s_1,s_2,\ldots,s_n\}$. I would like to to produce the following list of strings: $$ \{s_1<>1,\ 1<>s_2<>1,\ldots,\ 1<>s_n\} $$ In other words, I want to append the character $1$ to the end of the first string, to either end of all internal strings, and to the beginning of the final string. What is an efficient way to achieve this?

$\endgroup$
1
  • 2
    $\begingroup$ If efficiency paramount, check my answer, and note that the Riffle based solution will break if strings contain spaces, unless you use a dummy character - which cannot exist in any string - possibly slowing further... $\endgroup$
    – ciao
    Jun 25, 2015 at 5:06

3 Answers 3

7
$\begingroup$
Flatten[
 {#[[1]] <> "1", StringInsert[#[[2 ;; -2]], "1", {1, -1}], 
  "1" <> #[[-1]]}] &@strings

About 2X to over 10X as fast (depending on string lengths) as Riffle et al. that I noted in comment, and unlike that this will return correct results if strings contain spaces. About 4X as fast as mapping (all tested on MMA 9).

$\endgroup$
2
  • $\begingroup$ That's the way go to IMO. $\endgroup$
    – Mr.Wizard
    Jun 25, 2015 at 6:54
  • $\begingroup$ Nice. Can't believe it's that much faster though. Crazy. (+1) $\endgroup$
    – kale
    Jun 25, 2015 at 11:59
13
$\begingroup$

Here's a way with v10.1:

strings = {"a", "b", "c", "d", "e"};

StringSplit@StringRiffle[strings, "1 1"]

{"a1", "1b1", "1c1", "1d1", "1e"}

And if you're not on 10.1 (and as suggested by @ciao), you can achieve the same thing with:

StringSplit@StringJoin@Riffle[strings, "1 1"]

And just for the heck of it with MapIndexed:

MapIndexed[If[First@#2 == 1, "", "1"] <> #1 <> 
 If[First@#2 == Length@strings, "", "1"] &, strings]
$\endgroup$
1
  • $\begingroup$ +1 - and a similar construct (I won't post since it's the same in essence) for pre 10.x of StringSplit@StringJoin[Riffle[s, "1 1"]] is considerably faster than mapping solutions.... $\endgroup$
    – ciao
    Jun 24, 2015 at 23:40
5
$\begingroup$

Pedestrianly,

x = {"a", "b", "c", "d"};

Flatten[{StringJoin[#, "1"] &@First[x],
  StringJoin["1", #, "1"] & /@ x[[2 ;; -2]],
  StringJoin["1", #] &@Last[x]}]

{"a1", "1b1", "1c1", "1d"}

$\endgroup$
2
  • 2
    $\begingroup$ Hehe, learned a new adverb just now 😊 $\endgroup$
    – Yves Klett
    Jun 24, 2015 at 21:49
  • $\begingroup$ Like 'prosaic'. (Prose, but not poetry.) $\endgroup$ Jun 24, 2015 at 22:09

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.