Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting multiple strings into an element

Below is a small extract of a very large file.

I'm looking for a way to get each name and value (on the Name(x) and Value(x) lines) into an element of a Array or List type with an "=" between the two.

i.e to get each element to look like " 'name' = 'value' ".

[Device|EEP_FEATUREKOI_HFS_Max|Kostia]
--------------------------------
Name(1) = partHeader_A01
Value(1) = 0x10
Desc(1) = (Address 0x000) Article No. / P.C.B No Byte 1
Name(2) = partHeader_A02
Value(2) = 0x9
Desc(2) = (Address 0x001) Article No. / P.C.B No Byte 2
Name(3) = partHeader_A03
Value(3) = 0x95
Desc(3) = (Address 0x002) Article No. / P.C.B No Byte 3
Name(4) = partHeader_A04
Value(4) = 0x38
Desc(4) = (Address 0x003) Article No. / P.C.B No Byte 4
----------------------------------
Name(12) = AdrIctPcbTestDate_Day
Value(12) = 0xFF
Desc(12) = (Address 0x00B) Test Date : Day
---------------------------------
Name(13) = AdrIctPcbTestDate_Month
Value(13) = 0xFF
Desc(13) = (Address 0x00C) Test Date : Month
---------------------------------
Name(14) = AdrIctPcbTestTime_Hour
Value(14) = 0xFF
Desc(14) = (Address 0x00D) Test Time : Hour
---------------------------------
Name(15) = AdrIctPcbTesTime_Minute
Value(15) = 0xFF
Desc(15) = (Address 0x00E) Test Time : Minute

So far I can get the names and values. My problem is, when a section has more than 1 byte(denoted with a "_" in the name) I need to place all the byte values in the same element with only one name.

I can't figure out the proper algorithm to get this to work right.

i.e, for partHeaderArtLK_A01 up to partHeaderArtLK_A04, instead of having

partHeaderArtLK_A01 = 10

partHeaderArtLK_A02 = 09

partHeaderArtLK_A03 = 95

partHeaderArtLK_A04 = 38

The element would should to look like

partHeaderArtLK = 10 09 95 38.

(Note: I inserted the dashed line seperators to make things clearer. They don't (and cannot) exist in the actual file.)

Here's my attempt so far:

if (line.contains("Name")&& line.contains("_")) {
   String basicName = line;
   cutName = basicName.split("=")[1].trim();//get substring after '='
   cutName = cutName.substring(0,cutName.lastIndexOf("_"));//removes '_'?

   importantName.add(i, (cutName + " = "));//add to element i
   System.out.println("Line reads: " + basicName);
   System.out.println("Part: " + cutName);

   do{                   
    if (line.contains("Value")) {
      Hex = line.split("=")[1].trim();//get substring after '='
      importantNumber.add(i, Hex);//get substring after '='
      System.out.println("Value: " + Hex);                        
    }//end if                  
  }while(!"Value".contains(line = reader.readLine()));
   while (!placeToFinish[i].equals(line = reader.readLine()));

 }else    
   if(line.contains("Name")) {
     String basicName = line;
     cutName = basicName.split("=")[1].trim();//get substring after '='

     importantName.add(i, (cutName + " = "));//get substring after '='
     System.out.println("Line reads: " + basicName);
     System.out.println("Part: " + cutName);
     System.out.println("Number: " + importantNumber.indexOf(i) + "\n"); 

    do{  
      if (line.contains("Value")) {
       Hex = line.split("=")[1].trim();//get substring after '='
       importantNumber.add(i, Hex);//get substring after '='
     }//end if                    
   }while (!"Value".contains(line = reader.readLine()));
    while (!placeToFinish[i].equals(line = reader.readLine()));
 }//end if

Here's the link to the full code: http://justpaste.it/d3u0
All algorithms or code is appreciated.

Thanks in advance!

like image 565
user2798632 Avatar asked Oct 02 '22 21:10

user2798632


2 Answers

The way you are doing it is a little bit complicated (sorry I didn't even read the hole code).

From the output you are wanting to have, this is how I would do it:

I would use a Map which has as key the name without the the part after the underscore and as value a List of values.

I.e.:

When you read a line starting with Name extract that name from the line and remove the part after the the underscore (including). Save that name in variable whitch remains persistent through the loops.

When you read a line starting with Value extract the value again and look up the corresponding List from the Map using the name you have saved before. If the List does not exist, then create one and put it into the Map. Then add the value into the List.

Here is how it looks like:

private Map<String, List<String>> readValues(BufferedReader reader) throws IOException {
    Map<String, List<String>> nameToValuesMap  = new HashMap<String, List<String>>();
    String line = null;
    String actName = null; 
    while((line = reader.readLine()) != null) {
        if(line.startsWith("Name")) {
            String[] split = line.split("\\s*=\\s*", 2);
            String name = split[1];
            int i = name.indexOf('_');
            if(i != -1) {
                name = name.substring(0, i);
            }
            actName = name;
        } else if(line.startsWith("Value")) {
            String[] split = line.split("\\s*=\\s*", 2);
            String value = split[1].replace("0x", "");
            if(actName != null) {
                List<String> values = nameToValuesMap.get(actName);
                if(values == null) {
                    values = new ArrayList<String>();
                    nameToValuesMap.put(actName, values);
                }
                values.add(value);
            }
        }
    }

    return nameToValuesMap;
}

And for some testing I used the sample text you have posted:

@Test
public void readpartValues() throws IOException {
    String fielData = "[Device|EEP_FEATUREKOI_HFS_Max|Kostia]\r\n" + 
            "--------------------------------\r\n" + 
            "Name(1) = partHeader_A01\r\n" + 
            "Value(1) = 0x10\r\n" + 
            "Desc(1) = (Address 0x000) Article No. / P.C.B No Byte 1\r\n" + 
            "Name(2) = partHeader_A02\r\n" + 
            "Value(2) = 0x9\r\n" + 
            "Desc(2) = (Address 0x001) Article No. / P.C.B No Byte 2\r\n" + 
            "Name(3) = partHeader_A03\r\n" + 
            "Value(3) = 0x95\r\n" + 
            "Desc(3) = (Address 0x002) Article No. / P.C.B No Byte 3\r\n" + 
            "Name(4) = partHeader_A04\r\n" + 
            "Value(4) = 0x38\r\n" + 
            "Desc(4) = (Address 0x003) Article No. / P.C.B No Byte 4\r\n" + 
            "----------------------------------\r\n" + 
            "Name(12) = AdrIctPcbTestDate_Day\r\n" + 
            "Value(12) = 0xFF\r\n" + 
            "Desc(12) = (Address 0x00B) Test Date : Day\r\n" + 
            "---------------------------------\r\n" + 
            "Name(13) = AdrIctPcbTestDate_Month\r\n" + 
            "Value(13) = 0xFF\r\n" + 
            "Desc(13) = (Address 0x00C) Test Date : Month\r\n" + 
            "---------------------------------\r\n" + 
            "Name(14) = AdrIctPcbTestTime_Hour\r\n" + 
            "Value(14) = 0xFF\r\n" + 
            "Desc(14) = (Address 0x00D) Test Time : Hour\r\n" + 
            "---------------------------------\r\n" + 
            "Name(15) = AdrIctPcbTesTime_Minute\r\n" + 
            "Value(15) = 0xFF\r\n" + 
            "Desc(15) = (Address 0x00E) Test Time : Minute";


    BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(fielData.getBytes())));

    Map<String, List<String>> nameToValuesMap  = readValues(reader);
    reader.close();

    List<String> partHeaderValues = nameToValuesMap.get("partHeader");
    System.out.println("partHeader = " + partHeaderValues.toString());

    List<String> adrIctPcbTestTimeValues = nameToValuesMap.get("AdrIctPcbTestTime");
    System.out.println("AdrIctPcbTestTime = " + adrIctPcbTestTimeValues.toString());
}

Output

partHeader = [10, 9, 95, 38]
AdrIctPcbTestTime = [FF]

Hope this helps!

like image 167
A4L Avatar answered Oct 13 '22 10:10

A4L


Base idea - to create output map like "name -> (list of values)". Thereafter - print it. But I not sure, is java suitable instrument for solve this task. See my program on PERL, which does this job:

#!/usr/local/bin/perl -w

my %nv;
while(<>) {
  my ($nm, $ndx, $val) = m/^(\w+)?\((\d+)\)\s*=\s*(\w+)/;
  next unless $val;
  $nv{$ndx}{$nm} = $val;
}

my %out;
foreach my $k(sort keys %nv) {
  my $name = $nv{$k}{"Name"};
  $name =~ s/_.+//;
  push(@{$out{$name}}, map {s/^0x//; $_ } $nv{$k}{"Value"});
}

while(my ($nm, $vlist) = each %out) {
  print "$nm = " . join(" ", @{$vlist}) . "\n";
}

Output for your sample:

$ ./nv.pl nv.txt
AdrIctPcbTesTime = FF
AdrIctPcbTestDate = FF FF
partHeader = 10 9 95 38
AdrIctPcbTestTime = FF
like image 30
olegarch Avatar answered Oct 13 '22 11:10

olegarch