6
$\begingroup$

As a minimal working example:

myString="some words";
myString=myString<>"more words";

Is there a shorter way to tell Mathematica that I want to "tack on" more to the end of a string? For example "C-style":

myString<>="more words";

NB: I am aware of StringInsert[myString,"more words",-1]. I am looking specifically for an expression like <>= where I can use shorthand like <>= (or something else if that's not possible) to achieve the end result.

Thanks for your insight.

$\endgroup$
2
  • 2
    $\begingroup$ Belisarius showed how to make your own, but honestly I think that such an AddTo equivalent for strings would significantly reduce the readability of your code. I would argue that even the regular AddTo and friends are not all that readable. $\endgroup$
    – MarcoB
    Aug 7, 2015 at 16:46
  • $\begingroup$ @MarcoB, I totally agree if this is for stuff that you code into a larger program/Module. However, if you want to experiment or do stuff interactively, then such shorthands are sometimes nice. $\endgroup$ Aug 7, 2015 at 16:51

4 Answers 4

8
$\begingroup$

Even though belisarius' answer is probably closest to what you want, I find that I quite often do something like this:

SetAttributes[sj,HoldFirst];
sj[x_Symbol, y__] := (x = StringJoin[x, y])

Now we can type

myString = "some words ";
sj[myString, "more words"];
myString
(* "some words more words" *)

That is, instead of using infix notation lhs someoperator rhs, you can make shorthands that "wrap": someoperator[lhs,rhs]. I got used to it quickly. Note that we can even append more strings since we used y__:

myString = "some words ";
sj[myString, "more words ","even more words"];
myString
(* "some words more words even more words" *)
$\endgroup$
5
  • $\begingroup$ Just in case ...sj[x_Symbol, y__] := (x = StringJoin[x, y]) $\endgroup$ Aug 7, 2015 at 17:02
  • $\begingroup$ Doesn't HoldFirst guarantee that? Or have I misunderstood something... $\endgroup$ Aug 7, 2015 at 17:05
  • 2
    $\begingroup$ It's to be able to prevent sj["a", "more words ", "even more words"] $\endgroup$ Aug 7, 2015 at 17:07
  • $\begingroup$ I'm accepting this as the best answer. It seems to handle most cases, and @belisarius comment using x_Symbol is very helpful. Thanks! $\endgroup$ Aug 7, 2015 at 17:46
  • 1
    $\begingroup$ Of course, this is infix-able: myString ~sj~ "more words". $\endgroup$ Aug 7, 2015 at 22:33
6
$\begingroup$

Define your own:

<< Notation`
Notation[DoubleLongLeftRightArrow[
  ParsedBoxWrapper[
   RowBox[List["x_", " ", "⊕", " ", "y_", " "]]], 
  ParsedBoxWrapper[
   RowBox[List[" ", 
     RowBox[List["x_", "=", RowBox[List["x_", "<>", "y_"]]]]]]]]]

x = "caca";
x⊕"test";
x
(*"cacatest"*)

Edit

Using the Notation palette you should see

Mathematica graphics

$\endgroup$
6
  • $\begingroup$ Of course x\[CirclePlus]"test"\[CirclePlus]" nocreo" doesn't work this way! But e += 1 += 2 doesn't work either :D $\endgroup$ Aug 7, 2015 at 16:41
  • $\begingroup$ It doesn't work, I'm on Mathematica 10.2? I copy-pasted exactly your code and I get an erro he notation 'g[ x_,y_] x_ \[CirclePlus] y_ ' is not of the form \ externalBoxes \[DoubleLongLeftRightArrow] internalExpression or \ externalBoxes \[DoubleLongRightArrow] internalExpression or \ externalBoxes \[DoubleLongLeftArrow] internalExpression. Examine the \ full box structures for possible unintended groupings. $\endgroup$ Aug 7, 2015 at 16:46
  • $\begingroup$ @space_voyager I probably copied it wrong. Try again, please $\endgroup$ Aug 7, 2015 at 16:57
  • $\begingroup$ @belisarius I tried too and it fails. It produces this error The defined current default input format StandardForm differs from the current default output format TraditionalForm. The WorkingForm option will default to the current default output format, but the Notations, Symbolizations, and InfixNotations may behave differently than expected. >> $\endgroup$
    – chris
    Aug 7, 2015 at 17:51
  • $\begingroup$ in fact the error comes when loading the Notation package. $\endgroup$
    – chris
    Aug 7, 2015 at 17:52
3
$\begingroup$

I am not sure if this is the best method, but I found this article which describes mathematica operators without predefined definitions. I used one to associate a function with the TildeTilde symbol, made by pressing esc+~+~+esc.

SetAttributes[TildeTilde, HoldFirst]
TildeTilde[a_Symbol, b_String] := (a = a <> b)

You need to use HoldFirst attribute so that it doesn't evaluate your symbol before evaluating the expression

Now using myString $\approx$ "morewords" will work like <>=

$\endgroup$
2
  • $\begingroup$ Why Evaluate[a] ? $\endgroup$
    – shrx
    Aug 7, 2015 at 17:01
  • $\begingroup$ It may not be necessary. I was thinking that you might need it due to the HoldFirst attribute and put it there to be safe. I am not near a computer to see if it's necessary. If it works without it, feel free to edit it :) $\endgroup$
    – BenP1192
    Aug 7, 2015 at 17:14
0
$\begingroup$

This can also be done using operators.

SetAttributes[DotEqual, HoldFirst];
DotEqual[a_Symbol, b_] := a = b@a; 

oStringJoin[h_] := Function[expr, StringJoin[expr, h], HoldAll];

myString = "some words ";
myString \[DotEqual] oStringJoin@"more words";

myString

(* "some words more words"  *)

Such an approach is general in the sense that can it be used for any other modifications including those with the variables parts and applying built-in operator forms (in which case you don't need to roll your own as with oStringJoin - currently all the string operators don't have operator forms but I would anticipate this changing over time). An example of other modifications with existing operator forms

enter image description here

Readability would be probably improved by using @= instead of \[DotEqual] as discussed here.

$\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.