I'm working on a small side project and need to join an array from one element to another - so if my array is:
{"1","2","3","4","5"}
I would like my output to be in the form of
startingElement|elementsInBetween|endingElement
my code for this section looks like this:
int lastTwo = Integer.parseInt(String.join("",numberArray[numberArray.length-2],
numberArray[numberArray.length-1]))
This works for when I want the last two digits (in this case Strings needed to be converted to int) but I now need to join all elements except the last one.
I wrote up a solution which involved making a new array comprised of the elements of the original array minus the last element, and then using the String.join method on the new array. But I feel like this is horribly inefficient.
Edit:
Here is the testing solution I came up with:
String[] test = {"a", "b", "c","d","e","f"};
String[] test1 = new String[test.length-2];
for(int i =0; i< test1.length; i++){
test1[i] = test[i];
}
as I stated, this does technically do what I want, but I feel like a cleaner solution is available...
Try this
StringBuffer get(String[] arr){
StringBuffer buffer = new StringBuffer();
for(int i = 0; i < arr.length - 2; i++) buffer.append(arr[i]);
return buffer;
}
Related
My question is the same as this one except that instead of a single Document I have an array (Document[]).
I normally use R, not Java, so I apologize if it should be apparent how to change the solution from the linked thread for the case of an array.
The solution for the case of a single Document object was:
String htmlString = doc.html();
My code to create the object was:
Document[] target = new Document[20];
for(int n=0; n < strvec.length;n++){
target[n] = Jsoup.connect(strvec[n]).get();
}
I tried a few things like creating the original target object as String[], putting .toString() on the end of Jsoup.connect(strvec[n]).get() and elsewhere, but these attempts were unsucessful.
it is assumed that serves is an array of String containing the URL to connect, you do not need to create another array of Document
String[] result = new String[strvec.length];
for(int n=0; n < strvec.length;n++)
result[n]=Jsoup.connect(strvec[n]).get().html();
String[] htmlList = new String[target.length];
for(int i = 0; i < target.length; i++)
htmlList[i] = target[i].html();
This loop should do what you want.
There is a string[] arr = {"aa-bb-cc","dd-bb-ee","aa-hh-gg"} which needs to be split on the basis of , and -. The values aa,dd,aa should be stored in one list whereas bb,hh in another list. I have written this code snippet:
String[] arr = {"aa-bb-cc","dd-bb-ee","aa-hh-gg"};
for(int i=0;i<arr.length;i++){
newArr = arr[i].split(",");
for(int j=0;j<newArr.length;j++){
resultArr = newArr[j].split("-");
appList.add(resultArr[0]);
prodList.add(resultArr[1]);
rolList.add(rresultArr[2]ol);
}
Above approach could be better if we do arr[i].split in another way so that we can run only one loop but I could not achieve that so far.
I wanted to know is there any best way to achieve the requirement.
You don't need to split it using , ,since it's not part of the String but part of the String array declaration syntax,just split it with a -
String[] arr = {"aa-bb-cc","dd-bb-ee","aa-hh-gg"};
for(int i=0;i<arr.length;i++){
newArr = arr[i].split("-");
appList.add(newArr[0]);
prodList.add(newArr[1]);
rolList.add(newArr[2]);
}
I am learning Java and looking for a comprehensive code of multiplying the elements from 2 arrays, possibly without importing anything to achieve it.
In Python it's quite easy:
a=['a','b','c','d']
b=[1,2,3,4]
[x*y for x,y in zip(a,b)]
['a', 'bb', 'ccc', 'dddd']
How can I achieve the same thing in Java, when the first array is an array of strings and the second is integers?
I'm afraid Java isn't going to support this kind of thing natively, and you'll need to perform some of your own logic to implement it. Let's say you've got your String[]..
String[] a = {"a", "b", "c", "d"};
And you've got your int[]..
int[] b = {1,2,3,4};
Next, you'll need to check that the arrays are the same size.
if(a.length == b.length) {
// Continue.
}
Then you need to implement a loop, to go through each item in the arrays.
for(int x = 0; x < a.length; x++)
{
// Some looping code.
}
And you're going to grab each item.
String value = a[x];
int multiplier = b[x];
If you're not importing anything, you declare the total value:
String total = "";
But if you're allowing for a StringBuilder, then you'll import it and declare..
StringBuilder total = new StringBuilder();
NOTE: StringBuilder is strongly recommended here.
And then you're looping multiplier amount of times..
for(int y = 0; y < multiplier; y++)
{
// If you use StringBuilder..
total.append(value);
// If you don't..
total += value;
}
// If you use StringBuilder..
a[x] = total.toString();
// If you don't...
a[x] = total;
This will set the value of a[x] to the repeated String.
NOTE: Something that's also important is leaning good practise. If you're using Java code, it's considered terrible practise to repeatedly concatenate String objects. StringBuilder is more efficient, and is the Java standard. I would strongly recommend using this.
Have fun putting it all together!!
To create string filled with multiple instances of same character like "ccc" you can firs create array of characters which will hold only 3 characters like
char[] myCharacters = new char[3];
Now this array is filled with zeroes ('\0'), so you need to fill it with desired character 'c'. You simply do it using for loop
for (int i = 0; i<myCharacters; i++){
myCharacters[i] = 'c';
}
After this your array will contain ['c', 'c', 'c'].
Now you can use this array to create string using characters from it. To do so you just need to pass this array to String constructor like
String myString = new String(myCharacters);
And there you go. Now you have "ccc" String. Repeat these steps for each pair of elements from a and b arrays.
You can also use shorter version which kinds of do the same
String myString = new String(new char[3]).replace('\0','c');//will produce "ccc"
The question is about while-loops in which I need some code to be executed N times and some other code N+1 times. NOT about concatening Strings, I just use this as bad-coded yet short example.
Let me explain my question by providing an example.
Say I want to concatenate N+1 Strings, by glueing them with "\n", for example. I will have N+1 lines of text then, but I only need to add N times "\n".
Is there any boilerplate solution for this type of loop in which you have to execute some code N times and other code N+1 times? I'm NOT asking for solution to concatenate Strings! That is just a (bad) example. I'm looking for the general solution.
The problem I have with this is code duplication, so to code my example I'll do this (bad pseudo code, I know I have to use StringBuilder etc.):
String[] lines = <some array of dimension N+1>;
String total = lines[0];
for (int i = 1; i < N + 1; i++){
total += "\n" + lines[i];
}
The problem becomes worse if the code that has to be executed N+1 times, becomes larger, of course. Then I would do something like
codeA(); // adding the line of text
for (int i = 1; i < N + 1; i++){
codeB(); // adding the "\n"
codeA();
}
To remove the duplication, you can do this different by checking inside the loop, too, but then I find this quite stupid as I know beforehand that the check is pre-determined, as it will only be false the first iteration:
for (int i = 0; i < N + 1; i++){
if (i > 0){
codeB(); // adding the "\n"
}
codeA();
}
Is there any solution for this, a sort of while-loop that initializes once with codeA() en then keeps looping over codeB() and codeA()?
People must have run into this before, I guess. Just wondering if there are any beautiful solutions for this.
To my dissapointment, I believe that there is no such construct that satisfies the conditions as you have stated them and I will attempt to explain why (though I can't prove it in a strictly mathematical way).
The requirements of the problem are:
We have two parts of code: codeA() and codeB()
The two parts are executed a different number of times, N and N+1
We want to avoid adding a condition inside the loop
We want to execute each part only as many times as strictly necessary
2) is a direct consequence of 1). If we didn't have two parts of code we would not need a different number of executions. We would have a single loop body.
4) is again a consequence of 1). There is no redundant execution if we have a single loop body. We can control its execution through the loop's condition
So the restrictions are basically 1) and 3).
Now inside the loop we need to answer two questions on each iteration: a) do we execute codeA()? and b) do we execute codeB()? We simply do not have enough information to decide since we only have a single condition (the condition of the loop) and that condition will be used to decide if both of the code parts would be executed or not.
So we need to break 1) and/or 3) Either we add the extra condition inside the loop or we delegate the decision to some other code (thus not having two parts anymore).
Apparently an example of delegation could be (I am using the string concatenation example):
String [] lines = ...
for (int i = 0; i < N; i++){
// delegate to a utility class LineBuilder (perhaps an extension of StringBuilder) to concatenate lines
// this class would still need to check a condition e.g. for the first line to skip the "\n"
// since we have delegated the decisions we do not have two code parts inside the loop
lineBuilder.addLine( lines[i] );
}
Now a more interesting case of delegation would be if we could delegate the decision to the data itself (this might worth keeping in mind). Example:
List<Line> lines = Arrays.asList(
new FirstLine("Every"), // note this class is different
new Line("word"),
new Line("on"),
new Line("separate"),
new Line("line") );
StringBuffer sb = new StringBuffer();
for (Line l : lines) {
// Again the decision is delegated. Data knows how to print itself
// Line would return: "\n" + s
// FirstLine would return: s
sb.append( l.getPrintVersion() );
}
Of course all of the above does not mean that you couldn't implement a class that tries to solve the problem. I believe though this is beyond the scope of your original question not to mention that would be an overkill for simple loops
Concatenating Strings like this is a bad idea and a much bigger issue IMHO.
However to answer your question I would do
String sep = "";
StringBuilder sb= new StringBuilder();
for(String s: lines) {
sb.append(sep).append(s);
sep = "\n";
}
String all = sb.toString();
Note: there is usually a good way to avoid needing to create this String at all such a processing the lines as you get them. It is hard to say without more context.
This kind of thing is fairly common, like when you build sql. This is the pattern that I follow:
String[] lines ...//init somehow;
String total = lines[0];
boolean firstTime = true;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++){
if(firstTime) firstTime = false;
else sb.append('\n');
sb.append(lines[i]);
}
Note that this is not the same, as the first example and here is why:
String[] lines = <some array of dimension N+1>;
String total = lines[0];
for (int i = 1; i < N + 1; i++){
total += "\n" + lines[i];
}
Assuming you have an array of [0] = 'line1' and [1] = 'line2'
Here you end up with line1line2\n, when the desired output is:
line1\nline2.
The example I provided is clear, and does not perform poorly. In fact a much bigger performance gain is made by utilizing StringBuilder/Buffer. Having clear code is essential for the pro.
Personally i have most of the time the same problem, on the String example i use the StringBuilder as you said, and just delete the characters added to much:
StringBuilder sb = new StringBuilder();
for(int i=0; i<N; i++) {
sb.append(array[i]).append("\n");
}
sb.delete(sb.length-1, sb.length); // maybe check if sb contains something
In the common case i suppose there is no other way than adding the if you suggested. To make the code more clear i would check at the end of the for loop:
StringBuilder sb = new StringBuilder();
for(int i=0; i<N; i++) {
sb.append(array[i]);
if(i < N) {
sb.append("\n");
}
}
But i totally agree this is sad to have this double logic
I need to convert a string vector in a simple string. I do not know how to proceed.
I tried various solutions such as
for(int i=1; i < easy.length; i++){
easyPuzzle = easy[i].toString();
}
System.out.println(" " + easyPuzzle);
but this solution prints only the ith element and not the entire string vector.
Use toString in Arrays class
Arrays.toString(easy);
You keep reassign a new value to easyPuzzle when you really want to concatenate:
easyPuzzle += easy[i].toString();
If easy.length is large, it might make sense to use a StringBuilder which is more efficient at concatenating than String:
StringBuilder builder = new StringBuilder();
for(int i=1; i < easy.length; i++){
builder.append(easy[i].toString());
}
easyPuzzle = builder.toString();
Also by starting your for loop at i=1 you exclude the first item. Not sure if it is on purpose or not. If not, start at i = 0.
Alternatively, to save the pain of writing the loop yourself, you can use #Manoj's answer which replaces your code by one line.
I recommend to you use StringBuilder with append(<data>) method and then convert it to String.
StringBuilder data = new StringBuilder();
for(int i = 1; i < easy.length; i++){
data.append(easy[i].toString());
}
easyPuzzle = data.toString();
String is immutable so work with it is much more consume. When you work with String, i recommend to you use StringBuilder, is more effective and faster.
Update: #Manoj answer is very usefull.