I am trying to split up my info first into a String[] by using "\n" as delimiter and than afterwards ,split them again into a String[] but this time using ";" as delimiter.
I however fail at getting info out of the second split.
public static void initHashMap(){
String[] lijnen = readDefinitioncsv(definitioncsv).split("\n");
for (int i =2;i<lijnen.length;i++){
String[] detaillijn = lijnen[i].split(";");
// on the line below I get
//java.lang.ArrayIndexOutOfBoundsException: 1
int rood = Integer.parseInt(detaillijn[1]);
int groen = Integer.parseInt(detaillijn[2]);
int blauw = Integer.parseInt(detaillijn[3]);
String provincieNaam = detaillijn[4];
RGBProvince.put(new Color(rood,groen,blauw), provincieNaam);
}
}
Thank you for your time
String[] lijnen = readDefinitioncsv(definitioncsv).split("\r?\n");
for (int i =2;i<lijnen.length;i++){
String[] detaillijn = lijnen[i].split("[,;\t]");
if (detaillijn.length < 5) {
throw new IllegalArgumentException("Weiniger als 5 elementen: "
+ lijnen[i]);
}
This handles Windows line endings (\r\n aka CR+LF) and also other forms of CSV - as ; did not seem to function.
May the file ends with an empty line, in which case you need to skip that with a continue.
For good order, indices start at 0; you seem to be skipping 2 header lines, and the first column.
Why is your for loop initializing at the third position?
for (int i =2;i<lijnen.length;i++){
presumably you want i=0?
also you array might not have 2 elements:
int rood = Integer.parseInt(detaillijn[1]);
this is the second position. but it might have nothing because of the loop above.
You should probably check you have at least those many lines / columns before you hop straight to one in an array.
You're initializing i to 2 in your for loop. If your array has less than three items, you will get an index out of bounds trying to access a location that does not exist.
Why not start with int i = 0?
Related
I have a String which always looks like this:
data
data
data
data
non-data
non-data
And I need to delete the 2 last lines from it. The lenght of these lines can be different. How I can do that fast (String = ~1000 lines)?
I'd say something along the lines of:
String[] lines = input.split("\n");
String[] dataLines = Arrays.copyOfRange(lines, 0, lines.length - 2);
int lastNewLineAt = string.lastIndexOf("\n");
string.subString(0, string.lastIndexOf("\n", lastNewLineAt));
You can use constant for new line character reading system property
This Code will split your text by "\n" 's which means your lines in to a String Array.
Than you will get that array's length..
And in a for loop you will set and append your text till your length-1 element.
This may be a long approach but I was searching this and I couldn't find anything.
This was my easiest way.
String[] lines = YourTextViev.getText().toString().split("\n");
YourTextView.setText(""); // clear your TextView
int Arraylength = lines.length-1; // Changing "-1" will change which lines will be deleted
for(int i=0;i<Arraylength;i++){
YourTextView.append(lines[i]+"\n");
}
How would I remove the chars from the data in this file so I could sum up the numbers?
Alice Jones,80,90,100,95,75,85,90,100,90,92
Bob Manfred,98,89,87,89,9,98,7,89,98,78
I want to do this so for every line it will remove all the chars but not ints.
The following code might be useful to you, try running it once,
public static void main(String ar[])
{
String s = "kasdkasd,1,2,3,4,5,6,7,8,9,10";
int sum=0;
String[] spl = s.split(",");
for(int i=0;i<spl.length;i++)
{
try{
int x = Integer.parseInt(spl[i]);
sum = sum + x;
}
catch(NumberFormatException e)
{
System.out.println("error parsing "+spl[i]);
System.out.println("\n the stack of the exception");
e.printStackTrace();
System.out.println("\n");
}
}
System.out.println("The sum of the numbers in the string : "+ sum);
}
even the String of the form "abcd,1,2,3,asdas,12,34,asd" would give you sum of the numbers
You need to split each line into a String array and parse the numbers starting from index 1
String[] arr = line.split(",");
for(int i = 1; i < arr.length; i++) {
int n = Integer.parseInt(arr[i]);
...
try this:
String input = "Name,2,1,3,4,5,10,100";
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
You can make use of the split method of course, supplying "," as the parameter, but that's not all.
The trick is to put each text file's line into an ArrayList. Once you have that, move forwars the Pseudocode:
1) Put each line of the text file inside an ArrayList
2) For each line, Split to an array by using ","
3) If the Array's size is bigger than 1, it means there are numbers to be summed up, else only the name lies on the array and you should continue to the next line
4) So the size is bigger than 1, iterate thru the strings inside this String[] array generated by the Split function, from 1 to < Size (this will exclude the name string itself)
5) use Integer.parseInt( iterated number as String ) and sum it up
There you go
Number Format Exception would occur if the string is not a number but you are putting each line into an ArrayList and excluding the name so there should be no problem :)
Well, if you know that it's a CSV file, in this exact format, you could read the line, execute string.split(',') and then disregard the first returned string in the array of results. See Evgenly's answer.
Edit: here's the complete program:
class Foo {
static String input = "Name,2,1,3,4,5,10,100";
public static void main(String[] args) {
String[] strings = input.split(",");
int result=0;
for (int i = 1; i < strings.length; i++)
{
result += Integer.parseInt(strings[i]);
}
System.out.println(result);
}
}
(wow, I never wrote a program before that didn't import anything.)
And here's the output:
125
If you're not interesting in parsing the file, but just want to remove the first field; then split it, disregard the first field, and then rejoin the remaining fields.
String[] fields = line.split(',');
StringBuilder sb = new StringBuilder(fields[1]);
for (int i=2; i < fields.length; ++i)
sb.append(',').append(fields[i]);
line = sb.toString();
You could also use a Pattern (regular expression):
line = line.replaceFirst("[^,]*,", "");
Of course, this assumes that the first field contains no commas. If it does, things get more complicated. I assume the commas are escaped somehow.
There are a couple of CsvReader/Writers that might me helpful to you for handling CSV data. Apart from that:
I'm not sure if you are summing up rows? columns? both? in any case create an array of the target sum counters int[] sums(or just one int sum)
Read one row, then process it either using split(a bit heavy, but clear) or by parsing the line into numbers yourself (likely to generate less garbage and work faster).
Add numbers to counters
Continue until end of file
Loading the whole file before starting to process is a not a good idea as you are doing 2 bad things:
Stuffing the file into memory, if it's a large file you'll run out of memory (very bad)
Iterating over the data 2 times instead of one (probably not the end of the world)
Suppose, format of the string is fixed.
String s = "Alice Jones,80,90,100,95,75,85,90,100,90,92";
At first, I would get rid of characters
Matcher matcher = Pattern.compile("(\\d+,)+\\d+").matcher(s);
int sum = 0;
After getting string of integers, separated by a comma, I would split them into array of Strings, parse it into integer value and sum ints:
if (matcher.find()){
for (String ele: matcher.group(0).split(",")){
sum+= Integer.parseInt(ele);
}
}
System.out.println(sum);
I have a list of words , there are 4 words, it cant contain more that 4 its just an example. I want to use just 2 of the words the rest of them should be ignored or deleted e.g :
String planets = "Moon,Sun,Jupiter,Mars";
String[] planetsArray = planets.split(",");
int numberOfPlanets = planetsArray.length;
the result i get is 4. How do i delete the rest of the words if my list contains more that 2 words ?
As suggested in your previous question, you can use
String[] fewPlanets = new String[]{planets[0], planets[1]};
Just make sure the planets array has 2 elements or more to avoid an ArrayIndexOutOfBoundsException. You can use length to check it: if (planets.length >= 2)
For a more sophisticated solution, you could also do this using System.arrayCopy() if you're using Java 1.5 or earlier,
int numberOfElements = 2;
String[] fewPlanets = new String[2];
System.arraycopy(planets, 0, fewPlanets, 0, numberOfElements);
or Arrays.copyOf() if you're using Java 1.6 or later:
int numberOfElements = 2;
String[] fewPlanets = Arrays.copyOf(planets, numberOfElements);
String planets = "Moon,Sun,Jupiter,Mars";
String[] planetsArray = planets.split(",");
if(planetsArray .length > 2){
String []newArr = new String[2];
newArr[0]=planetsArray [0];
newArr[1]=planetsArray [2];
planetsArray = newArr ;
}
Use Arrays.asList to get a List of Strings from String[] planetsArray.
Then use the methods of the List interface -contains,remove,add, ...- to simply do whatever you want on that List.
If you need to select the first 2 planets just copy the array:
String[] newPlanetsArray = Arrays.CopyOf(planetsArray, 2);
If you need to select 2 specific planets you can apply the following algorithm:
First, create a new array with 2 elements. Then, iterate through the elements in the original array and if the current element is a match add it to the new array (keep track of the current position in the new array to add the next element).
String[] newPlanetsArray = new String[2];
for(int i = 0, int j = 0; i < planetsArray.length; i++) {
if (planetsArray[i].equals("Jupiter") || planetsArray[i].equals("Mars")) {
newPlanetsArray[j++] = planetsArray[i];
if (j > 1)
break;
}
}
You could use an idea from How to find nth occurrence of character in a string? and avoid reading the remaining values from your comma separated string input. Simply locate the second comma and substring upto there
(Of course if your code snippet is just an example and you do not have a comma separated input, then please ignore this suggestion :)
I'm wondering how I could grab each nth lines from a String, say each 100, with the lines in the String being seperated with a '\n'.
This is probably a simple thing to do but I really can't think of how to do it, so does anybody have a solution?
Thanks much,
Alex.
UPDATE:
Sorry I didn't explain my question very well.
Basically, imagine there's a 350 line file. I want to grab the start and end of each 100 line chunk. Pretending each line is 10 characters long, I'd finish with a 2 seperate arrays (containing start and end indexes) like this:
(Lines 0-100) 0-1000
(Lines 100-200) 1000-2000
(Lines 200-300) 2000-3000
(Lines 300-350) 3000-3500
So then if I wanted to mess around with say the second set of 100 lines (100-200) I have the regions for them.
You can split the string into an array using split() and then just get the indexes you want, like so:
String[] strings = myString.split("\n");
int nth = 100;
for(int i = nth; i < strings.length; i + nth) {
System.out.println(strings[i]);
}
String newLine = System.getProperty("line.separator");
String lines[] = text.split(newLine);
Where text is string with your whole text.
Now to get nth line, do e.g.:
System.out.println(lines[nth - 1]); // Minus one, because arrays in Java are zero-indexed
One approach is to create a StringReader from the string, wrap it in a BufferedReader and use that to read lines. Alternatively, you could just split on \n to get the lines, of course...
String[] allLines = text.split("\n");
List<String> selectedLines = new ArrayList<String>();
for (int i = 0; i < allLines.length; i += 100)
{
selectedLines.add(allLines[i]);
}
This is simpler code than using a BufferedReader, but it does mean having the complete split string in memory (as well as the original, at least temporarily, of course). It's also less flexible in terms of being adapted to reading lines from other sources such as a file. But if it's all you need, it's pretty straightforward :)
EDIT: If the start indexes are needed too, it becomes slightly more complicated... but not too bad. You probably want to encapsulate the "start and line" in a single class, but for the sake of brevity:
String[] allLines = text.split("\n");
List<String> selectedLines = new ArrayList<String>();
List<Integer> selectedIndexes = new ArrayList<Integer>();
int index = 0;
for (int i = 0; i < allLines.length; i++)
{
if (i % 100 == 0)
{
selectedLines.add(allLines[i]);
selectedIndexes.add(index);
}
index += allLines[i].length + 1; // Add 1 for the trailing "\n"
}
Of course given the start index and the line, you can get the end index just by adding the line length :)
I have a file with data in the form timestamp, coordinate, coordinate, seperated by spaces, as here;
14:25:01.215 370.0 333.0
I need to loop through and add the coordinates only to an array. The data from the file is read in and put into as String[] called info, from split(" "). I have two problems, I think the end of the file has a extra " " which I need to lose appropriately and I also want confirmation/suggestions of my loop, at the moment I am getting sporadic out of bounds exceptions. My loop is as follows;
String[] info;
info = dataHolder.split(" ");
ArrayList<String> coOrds1 = new ArrayList<String>();
for (int counter = 0; counter < info.length; counter = counter+3)
{
coOrds1.add(info[counter+1]);
coOrds1.add(info[counter+2]);
}
Help and suggestions appreciated.
The text file is here but the class receives in a UDP packet from another class so I am unsure if this potentially adds " " at the end or not.
There are various classes/methods in Google's Guava library that could help with this task, in particular Splitter.omitEmptyStrings() which will discard any trailing space at the end of the file:
String input = Files.toString(file, Charsets.US_ASCII);
Iterable<String> fields =
Splitter.on(" ")
.omitEmptyStrings()
.split(input);
List<Coord> coords = Lists.newArrayList();
for (List<String> group: Iterables.partition(fields, 3)) {
String t = group.get(0);
double x = Double.parseDouble(group.get(1));
double y = Double.parseDouble(group.get(2));
coords.add(new Coord(t, x, y));
}
The problem will occur if you have an extra space at the end, because you are testing for counter < info.length and using counter + 1 and counter + 2. Try changing the loop conditions to:
for (int counter = 0; counter + 2 < info.length; counter = counter+3)
There is no need for external libraries.
You could just call dataHolder.trim(); which will remove any whitespace from the beginning and end your string. Then using dataHolder.split("\s"); //splits on "whitespace", you will receive an array consisting only of your data and with the appropriate size.
This will save you all the checks at each iteration whether counter+2 is still within the scope of the array. While still a valid solution, this could introduce further problems in the future due to its inherent nature of being "check-to-validate" - you simply might forget to process one of the cases - while trimming the string beforehand makes it structurally, constructed valid and there is no need to process special cases.