Reputation: 11
I have a program with a GUI where I insert a couple of hexes (String), press the search button, and I find the code for it. I import the all the hexes I have a code for from a CSV file. The thing I want is that if I enter for example: 11 D7 E2 FA
, my program would only search for the 2nd nibbles, x
meaning ignored: x1 x7 x2 xA
, and if it finds something like that in the CSV it gives me the code for it. This is what I have so far, this only finds me the cases when the strings match.
codeOutputField.setText("");
String input = hexEntryField.getText();
try {
br = new BufferedReader(new FileReader(FIS));
while ((line = br.readLine()) != null) {
code = line.split(csvSplitBy);
if (input.equals(code[0])) {
codeOutputField.setText(code[1]);
}
}
}
Sample CSV:
01 5F 1E CE,0055
01 5F 13 D0,0062
01 5E 36 FE,0101
00 5E 36 FF,1002
This is the code that works for me now, wanted to share it. Only problem I have now is that I can only run the jar
file from a bat
file, double-click does not work. I have no idea why.
String input = hexEntryField.getText();
String[] myStringArray = input.split("");
codeOutputField.setText("");
try {
br = new BufferedReader(new FileReader(FIS));
while ((line = br.readLine()) != null) {
code = line.split(csvSplitBy);
List<String> items = Arrays.asList(code[0].split(""));
System.out.println(items);
if (myStringArray[1].equals(items.get(1))
&& myStringArray[4].equals(items.get(4))
&& myStringArray[7].equals(items.get(7))
&& myStringArray[10].equals(items.get(10))) {
codeOutputField.setText(code[1]);
}
}
}
Upvotes: 1
Views: 1166
Reputation:
You can use a chain of predicates to compare even characters from a hex string and a search string:
// assume that we have an array of hexes
String[] hexes = {"015F1ECE", "015F13D0", "015E36FE", "005E36FF"};
// user input
String search = "035D3EFA";
// conditions to check
Predicate<String> predicateChain = IntStream
// even numbers 0, 2, 4, 6
.range(0, 4).map(i -> i * 2)
// compare even characters from the
// current string and the search string
// Stream<Predicate<String>>
.mapToObj(i -> (Predicate<String>)
str -> str.charAt(i) == search.charAt(i))
// reduce a stream of predicates
// to a single predicate chain
.reduce(Predicate::and)
// otherwise the condition is not met
.orElse(p -> false);
// output the filtered array
Arrays.stream(hexes).filter(predicateChain).forEach(System.out::println);
Output:
015E36FE
005E36FF
See also: Looking for similar strings in a string array
Upvotes: 1
Reputation: 9872
Your problem is more about parsing each line. I would combine some regular expressions:
public class Record {
private static final Pattern HEX_VALUE = Pattern.compile("[A-F0-9][A-F0-9]");
//...
public static Record from(String line) throws Exception {
Record record = new Record();
String[] parts = line.split(",");
if (parts.length != 2) {
throw new Exception(String.format("Bad record! : %s", line));
}
record.code = parts[1];
String hexes[] = parts[0].split("\\s");
if (hexes.length != 4) {
throw new Exception(String.format("Bad record! : %s", line));
}
for (String hex: hexes) {
if (!HEX_VALUE.matcher(hex).matches()) {
throw new Exception(String.format("Bad record! : %s", line));
}
}
record.hex1 = hexes[0];
record.hex2 = hexes[1];
record.hex3 = hexes[2];
record.hex4 = hexes[3];
return record;
}
...
@Override
public boolean equals(Object obj) {
boolean ret = false;
if (obj instanceof Record) {
Record r = (Record) obj;
ret = equalsSecondCharacter(this.hex1, r.hex1)
&& equalsSecondCharacter(this.hex2, r.hex2)
&& equalsSecondCharacter(this.hex3, r.hex3)
&& equalsSecondCharacter(this.hex4, r.hex4);
}
return ret;
}
...
And then just search into the list of records. In the example I have used Apache Commons Collections filtering:
while((line = br.readLine()) != null) {
records.add(Record.from(line));
}
// Check into the list
Collection<Record> filtered =
CollectionUtils.select(records, new EqualPredicate<Record>(inputRecord));
System.out.println("Results:");
for (Record rec: filtered) {
System.out.println(rec);
}
I hope you find it useful.
Upvotes: 1
Reputation: 431
Supposing code is declared as String code[2], you must get what you want making "csvSplitBy" equals to ","
or explicitely:
code = line.split(",");
Upvotes: 0