6

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.

space_voyager
  • 841
  • 4
  • 11
  • 2
    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. – MarcoB Aug 07 '15 at 16:46
  • @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. – Marius Ladegård Meyer Aug 07 '15 at 16:51

4 Answers4

8

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" *)
Marius Ladegård Meyer
  • 6,805
  • 1
  • 17
  • 26
6

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

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
  • Of course x\[CirclePlus]"test"\[CirclePlus]" nocreo" doesn't work this way! But e += 1 += 2 doesn't work either :D – Dr. belisarius Aug 07 '15 at 16:41
  • 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. – space_voyager Aug 07 '15 at 16:46
  • @space_voyager I probably copied it wrong. Try again, please – Dr. belisarius Aug 07 '15 at 16:57
  • @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. >> – chris Aug 07 '15 at 17:51
  • in fact the error comes when loading the Notation package. – chris Aug 07 '15 at 17:52
  • @chris Oh, well. Not in my Mma v9. Could someone else check it? – Dr. belisarius Aug 07 '15 at 17:52
3

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 <>=

BenP1192
  • 934
  • 6
  • 13
  • Why Evaluate[a] ? – shrx Aug 07 '15 at 17:01
  • 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 :) – BenP1192 Aug 07 '15 at 17:14
0

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.

Ronald Monson
  • 6,076
  • 26
  • 46