String concatenation questions

Hello,
i have data in customer field
1)address1 2)address2 3)city 4)state 5)zip code…

i need to concatenation into partner field with single name like
1)Mailing Address
above all customer address fields must me appear into one form;

i try to worked with -pub.string.concat,
and also using java service but i am getting error,
any one can help above problem ,and send me please the related steps or code.

how to do ?
please make it clearly
Thanks

APG,

The PSUtilities package has a multiConcat service (which is available from webMethods advantage portal).
I think it will solve your problem.

HTH,
Maldonado

Hi Maldonado,
Thanx for your reply,is there any other way to concat using pub.string.concat;we can add to strings using cocat …if we use multiple concats(pub.string.concat’s) to get the result.
some people given idea using java services but ,i dont know i am getting error.
Thank you very much for reply.
bye
APG

APG,

What is the error that you are getting?so that someone can help to debug.

HTH,
RMG

Try pub.string:makeString. When mapping the inputs, use the index to map each individual input string to positions in the elementList variable. There is no need to write a Java service to perform this–you can easily use what’s already built and tested.

Hello,

Yemi Bedu

Hi Seniors,
while adding more elements to makestrig i am getting bellow errors.i used in the add element lists all fields on that time i may not add more than one field.
may be i approched in wrong way ,please can u people clarify me.

I got the following ERROR.
[ISC.0049.9018] The path has been used: /elementList(0)

Click on the variable being mapped to the list. On the Properties pane you’ll see an Index (or Indices) button. Click it. Set the index for each of the mapped strings to be unique, starting at 0.

My quick and not so dirty multi concat:

==== start code

// pipeline in
IDataCursor pipelineCursor = pipeline.getCursor();

String delimiter = IDataUtil.getString(pipelineCursor, “delimiter”);
//default to empty string for delimiter
if (delimiter == null)
{
delimiter = “”;
}

StringBuffer strBuff = new StringBuffer();

boolean hasHadFirstString = false;

for (int i=0; i<= CONCAT_MAX_INPUT_STRINGS_NUMBER; i++)
{
String currentString = IDataUtil.getString( pipelineCursor, “inString”+i );
if (currentString!= null)
{
if (hasHadFirstString)
{
strBuff.append(delimiter);
}
else
{
hasHadFirstString = true;
}
strBuff.append(currentString);
}
}

IDataUtil.put( pipelineCursor, “value”, strBuff.toString() );
pipelineCursor.destroy();

==== end code

In the shared tab simply declare a variable:

private static int CONCAT_MAX_INPUT_STRINGS_NUMBER=10;

and create inputs:
delimiter
inString1
inString2
inString3

inStringN

where N is up to whatever number you set CONCAT_MAX_INPUT_STRINGS_NUMBER

that way if you need more later on, just create new inStringN inputs and bump up the number.
Never bump it DOWN however unless you’re sure that noone has used the extra inStringN pipeline variables.

Output will be the good old “value” output.

regards,
Nathan Lee
PS apologies about the formatting, couldn’t work out how to get spacing correct, pre tag doesn’t work, neither does nbsp’s… If I do certain combinations of “enable html code” and auto activate urls it breaks my code (chops off closing curly braces!)

Why not just use pub.string:makeString? It provides the same functionality (though setting the inputs takes a few more clicks) and doesn’t need to be modified when the max number of strings exceeds the max number the service will accept. And it’s available on every IS.

Aah, I tend to find that too much use of indexed array inputs is hard to visually see what’s going on (they’re all blue links going into a single element).
Generally you don’t need to stick more than a handful of things together, so the updating the number is only really a once or twice thing, can always set it up to be 20 and be done with it…

I find it a lot quicker to setup and readjust if you need to change the order or something(by quicker I mean less typing, more mouse arm RSI). I find the process of map, type index, click ok, map, type index, click ok is a bit slow compared to map map map done…

Anyhow, it’s just something I dump in the common package for whatever company I’m at and then it’s a reusable chunk.

Nath

When using such multiconcat service with many inputs or even makeString be ready for sizable performace hit. If you need to concat several strings say 3-5 in a long nested loops do not try to use Flow loop operation. It is best to write Java service that does such operations for performance. As an example on loop of 10000 elements with such concat services you can loose about 5-10 min of processing time.

Hello,

Yemi Bedu

The pub.string:makeString and pub.string.conat both are Java services as well as previosly discussed code is also Java. There is no problem with Java service itself although there are use cases of String + concatination vs StringBuffer.append that are faster depending on JVM and JIT optimizations. That is all well known Java programming stuff.
Specificaly pub.string:makeString may be more efficient than concat or custome Java concat service because it uses list as input instead of individual strings.

But I was talking about specific cases where these java services are used inside nested Flow loops. In that case replacenig Flow loop logic with direct Java loop logic that includes efficient java concatination provides significant performance gain at least in JVM 1.4.2. To start with just flow loop operation exec will account for about 40% of time. Bottom line is if you call even Java service you willl have to build PIPELINE objects and IS context to invoke these services. Also with 10 or 20 input fields there is compunded time to read and test each one even if you do not use most of them. These are perormance hits that accumulate on large loop itterations.

Yemi:
Not to put a dampener on your performance claims: but why is that of utmost importance (or really: any importance)? It is fairly unlikely you’ll be able by hand to physically supply enough inputs to see any performance difference between makestring/my multiconcat/your multi concat. Perhaps if you have 100,000 strings, but realistically: this is a convenience wrapper instead of calling concat a few times.

The solution you provide does indeed concatenate things together, but you’re comparing apples and oranges (and not explaining anything of your “preformance test”, sample data etc). The code is not equivilent for a start: yours has no ability to set a delimiter and also no ability to be used as a standalone service (as it iterates through the entire pipeline). Mine requires creation of a java service (and is thus a piece of custom code so is not out of the box, so requires more effort than makeString to get it written) and makeString is included functionality out of the box (thus development time “perfomance” beats yours and my solution).

Also: the focus on performance of something that sticks a few strings together: it’s micro optimising at best. There are far greater performance increases to be found by examining the macro-optimisations e.g. like reducing network round trips, allowing concurrent execution etc.

Igor does make a valid point about performance in loops: regardless of whether you have the most optimised “concat service” in the universe, if you output a new string and then concatenate something else to that next iteration of the loop it will make so little difference overall that the 0.000000001 of a nanosecond you shaved off by optimising your java service is lost by the cost of memory allocation over and over again. This is a problem in java as well as pretty much any language really. The solution for Strings and loop concatenation in java is StringBuffers.

So if you wanted to get good performance while still using loops rather than java services, try creating a couple of StringBuffer services, one to create an empty one, another to append, another to call toString on it. Just leave a StringBuffer sitting on the pipeline and keep passing it into the services as you go.

Reason I even bothered posting is that obsession with performance for learning developers is a bad idea, it encourages hacking over clean design, java services over flow (for no reason, leading to a maintenance nightmare).

Nathan Lee

Interesting points all.

To Nathan’s point about optimizing too soon, there’s a fairly well circulated notion about the 3 rules of optimization:

  1. Don’t optimize yet.
  2. Don’t optimize yet.
  3. Don’t optimize yet.

Some random thoughts spurred by the thread:

  • My original reason for posting “why not just use makeString?” is in sync with Nathan’s “…obsession with performance…encourages…java services over flow” where my knee-jerk reaction was “a service already exists, why do another one?” But Nathan rightly pointed out the
    the better readability and modifiability of the multi-concatservice. Though I think I would still use makeString rather than a custom multi-concat just to be ornery. :wink:

  • Igor’s point about performance in loops is good to keep in mind–once one determines that the loop is a meaningful bottleneck.

  • The biggest time killer in loops? Allocating objects, as both Igor and Nathan allude to.

  • One thing intriguing about Yemi’s approach to iterate over the pipeline is if the call to the service was scoped. This would let one control what variables are concat’d but I’d worry about the order.

Interesting thread.

Has been an interesting thread considering the fairly plain topic (e.g. concatenation)…

Optimisation rule: I always liked the magic saying (thanks to my first boss):
“the biggest performance increase you’ll EVER get is to go from the non-working state to the working state”

I treat that one as the golden rule, because at the end of the day you gotta get it working first, then worry about the details. So ease of development (realisability), understandability, clarity, maintainability tend to rate higher for me than raw-byte-code optimisations… As you go along you instinctively avoid any performance traps you’ve come across in the past and sit down and design things well to start with…

The scoped invoke, yeah, but then you need 3 flow operations (map to setup, invoke with scope, map to map out result) which starts looking a bit messy if you do it too much (I had to do a bunch of dynamic invoking of other services which needed this a handful of times, so I wrapped it up in a sequence to tidy things up).

Could also invoke it as a transformer service and add the variables by hand, but then you get to what mine (+/- a bit of key lookup expense) except that you have to add the variables each time/can choose whatever names you like.

Hi…How would i concatinate two string but appended to something…
Like i have STRING1 and STRING2

i need the ouput as STRING1+++STRING2

I need “+++” in between…
Please some one help me how to do that…
I didnt want 2 use append to string list, coz i want the ouput as string itself.

Thanx for ur help

use a map and in the map use pub.string.concat transform give input as string1 and +++, map the output to string1. use another map and again use pub.string.concat transform and give input as string1 and string2. you will get the desired string as output.
Thanks,
Jay

Basically rigid solution is to use 2 concat services
in concat1(STRING1,++++) map to concatString
in concat2(concatString,STRING2) map to multiConcat --this holds STRING1+++STRING2.

Or create a java service utility with the code below

Service Inputs (inString1,instring2,inString3)
Service Output(outStr)

String str1 = checkNull(in.getString(“inString1”));
String str2 = checkNull(in.getString(“inString2”));
String str3 = checkNull(in.getString(“inString3”));

String outStr = str1 + str2 + str3;

out.put( “outStr”, outStr );

Also put this code in Shared tab of Javaservice,to check for null values.

private static String checkNull(String inputString)
{
if( inputString == null )
return “”;
else
return inputString;
}

Save JS and test the service.

HTH,
RMG