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
    $\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 '15 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$ – Marius Ladegård Meyer Aug 7 '15 at 16:51
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$
  • $\begingroup$ Just in case ...sj[x_Symbol, y__] := (x = StringJoin[x, y]) $\endgroup$ – Dr. belisarius Aug 7 '15 at 17:02
  • $\begingroup$ Doesn't HoldFirst guarantee that? Or have I misunderstood something... $\endgroup$ – Marius Ladegård Meyer Aug 7 '15 at 17:05
  • 2
    $\begingroup$ It's to be able to prevent sj["a", "more words ", "even more words"] $\endgroup$ – Dr. belisarius Aug 7 '15 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$ – space_voyager Aug 7 '15 at 17:46
  • 1
    $\begingroup$ Of course, this is infix-able: myString ~sj~ "more words". $\endgroup$ – J. M. will be back soon Aug 7 '15 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$
  • $\begingroup$ Of course x\[CirclePlus]"test"\[CirclePlus]" nocreo" doesn't work this way! But e += 1 += 2 doesn't work either :D $\endgroup$ – Dr. belisarius Aug 7 '15 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$ – space_voyager Aug 7 '15 at 16:46
  • $\begingroup$ @space_voyager I probably copied it wrong. Try again, please $\endgroup$ – Dr. belisarius Aug 7 '15 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 '15 at 17:51
  • $\begingroup$ in fact the error comes when loading the Notation package. $\endgroup$ – chris Aug 7 '15 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$
  • $\begingroup$ Why Evaluate[a] ? $\endgroup$ – shrx Aug 7 '15 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 '15 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, privacy policy and cookie policy

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