英文:
Dividing a string into 3 parts and export to CSV in JAVA
问题
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> unit_list = Arrays.asList("g", "kg", "ml", "l");
List<String> quantity_list = Arrays.asList(
"Full", "Quarter", "Half", "3 Quarter",
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"
);
String input = "1 kg potatoes";
String[] inputParts = input.split(" ");
if (inputParts.length == 3) {
String quantity = inputParts[0];
String unit = inputParts[1];
String item = inputParts[2];
if (unit_list.contains(unit) && quantity_list.contains(quantity)) {
System.out.println("Unit Detected");
System.out.println("Quantity Detected");
// Write code to save the results into a CSV file
// with the columns Quantity, Unit, and Item
}
}
}
}
英文:
I have a string "1 kg potatoes" whereas 1 is the quantity, kg is the unit and potatoes is the item. I want that the compiler will read a string and match with "unit_list & quantity_list"(see code below). And it saves the results into 3 columns in a CSV file.
List<String> unit_list = Arrays.asList("g", "kg","ml","l");
List<String> quantity_list = Arrays.asList("Full", "Quarter", "Half", "3 Quarter", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
String input = "1 kg potatoes";
if (unit_list.equals(input)) {
System.out.println("Unit Detected");
}
if (quantity_list.equals(input)) {
System.out.println("Quantity Detected");
}
>Expected Output in CSV File
>
>Quantity, Unit, Item
>
>1, kg , potatoes
But this is not working for me. Please help me to do this.
答案1
得分: 0
EDIT: 基于您说过类似于"8 g carrots"可能是"8g carrots",我更新了原始代码并在底部添加了一个新方法。
以下是我提出的解决方案。由于您说顺序不保证,并且我们不需要检查"item"是否有效,我是这样做的:
public static void parseToCSV() throws IOException {
List<String> list = generateList();
List<String> unitList = Arrays.asList("g", "kg", "ml", "l");
List<String> quantityList = Arrays.asList("Full", "Quarter", "Half", "3 Quarter", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
for (String s : list) {
String[] strArr = s.split(" ");
// Checks if the String array is too short for what we need(i.e "8g carrots" instead of "8 g carrots")
if (strArr.length == 2) {
String newStr = rewriteString(strArr, quantityList);
strArr = newStr.split(" ");
}
String[] itemLine = new String[3];
for (int i = 0; i < strArr.length; i++) {
String str = strArr[i];
int index = findValueLocation(str, quantityList, unitList);
itemLine[index] = str;
}
String line = createLineForCSV(itemLine);
writeToFile(line);
}
}
private static List<String> generateList() {
List<String> list = new ArrayList<>();
String inputOne = "1 kg potatoes";
String inputTwo = "3 g juice";
String inputThree = "8g carrots";
list.add(inputOne);
list.add(inputTwo);
list.add(inputThree);
return list;
}
/**
* Return the index where the value should go in a comma-separated String. If the
* value is not found in either list then it is the item by default.
*/
private static int findValueLocation(String str, List<String> quantityList, List<String> unitList) {
for (String quantity : quantityList) {
if (quantity.equals(str)) {
return 0;
}
}
for (String unit : unitList) {
if (unit.equals(str)) {
return 1;
}
}
return 2;
}
private static String createLineForCSV(String[] itemLine) {
StringBuilder sb = new StringBuilder();
sb.append(itemLine[0]).append(",");
sb.append(itemLine[1]).append(",");
sb.append(itemLine[2]);
return sb.toString();
}
private static void writeToFile(String line) throws IOException {
// Set to true for append mode
BufferedWriter writer = new BufferedWriter(new FileWriter("csv_file.csv", true));
writer.write(line);
writer.newLine();
writer.close();
}
这在我的测试中是有效的。唯一的问题是,每次运行时它都会始终追加到CSV文件。如果您希望有一个选项来清除文件,以便可以重新写入所有数据,那么您可以添加这个方法:
private static void clearFile() throws IOException {
FileWriter writer = new FileWriter("csv_file.csv", false);
writer.write("");
writer.close();
}
EDIT: 解决"8g"而不是"8 g"的问题的新方法。这个方法的作用是检查拆分后的字符串是否长度为2。如果是,则没有正确分隔。我们检查quantityList,因为它不应该出现为"g8 carrots"。我们找到quantity,并创建一个新的字符串,格式为
private static String rewriteString(String[] arr, List<String> quantityList) {
String strOne = arr[0];
String strTwo = arr[1];
String newStr = "";
for (String quantity : quantityList) {
if (strOne.contains(quantity)) {
// 8g carrots becomes "8 g carrots"
newStr = quantity + " " + strOne.substring(quantity.length()) + " " + strTwo;
break;
} else if (strTwo.contains(quantity)) {
newStr = quantity + " " + strTwo.substring(quantity.length()) + " " + strOne;
break;
}
}
return newStr;
}
希望这对您有所帮助!
英文:
EDIT: Based on the fact that you said something like "8 g carrots" could be "8g carrots" I've updated the original code and added a new method to the bottom.
Here's the solution I came up with. Since you said order is not guaranteed, and we don't need to check if the "item" is valid, I did it this way:
public static void parseToCSV() throws IOException {
List<String> list = generateList();
List<String> unitList = Arrays.asList("g", "kg","ml","l");
List<String> quantityList = Arrays.asList("Full", "Quarter", "Half", "3 Quarter", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
for(String s : list) {
String[] strArr = s.split(" ");
// Checks if the String array is too short for what we need(i.e "8g carrots" instead of "8 g carrots")
if(strArr.length == 2) {
String newStr = rewriteString(strArr, quantityList);
strArr = newStr.split(" ");
}
String[] itemLine = new String[3];
for(int i = 0; i < strArr.length; i++) {
String str = strArr[i];
int index = findValueLocation(str, quantityList, unitList);
itemLine[index] = str;
}
String line = createLineForCSV(itemLine);
writeToFile(line);
}
}
private static List<String> generateList() {
List<String> list = new ArrayList<>();
String inputOne = "1 kg potatoes";
String inputTwo = "3 g juice";
String inputThree = "8g carrots";
list.add(inputOne);
list.add(inputTwo);
list.add(inputThree);
return list;
}
/**
* Return the index where the value should go in a comma separated String. If the
* value is not found in either list then it is the item by default.
*/
private static int findValueLocation(String str, List<String> quantityList, List<String> unitList) {
for(String quantity : quantityList) {
if(quantity.equals(str)) {
return 0;
}
}
for(String unit : unitList) {
if(unit.equals(str)) {
return 1;
}
}
return 2;
}
private static String createLineForCSV(String[] itemLine) {
StringBuilder sb = new StringBuilder();
sb.append(itemLine[0]).append(",");
sb.append(itemLine[1]).append(",");
sb.append(itemLine[2]);
return sb.toString();
}
private static void writeToFile(String line) throws IOException {
// Set to true for append mode
BufferedWriter writer = new BufferedWriter(new FileWriter("csv_file.csv", true));
writer.write(line);
writer.newLine();
writer.close();
}
This works when I tested it. The only thing is it will always append to the CSV file every time you run it. If you want an option to clear the file so you can write all the data fresh then you could just add this method:
private static void clearFile() throws IOException {
FileWriter writer = new FileWriter("csv_file.csv", false);
writer.write("");
writer.close();
}
EDIT: New method to fix issue of "8g" instead of "8 g". What this does is check if the split String has length of 2. If so then it is not separated properly. We check the quantityList, since it should never come as "g8 carrots". We find the quantity, and create a new string of <Quantity><space><Rest of String><space><Other String> and return that as the properly made String. Kind of a hacky solution, but it works for me.
private static String rewriteString(String[] arr, List<String> quantityList) {
String strOne = arr[0];
String strTwo = arr[1];
String newStr = "";
for(String quantity : quantityList) {
if(strOne.contains(quantity)) {
// 8g carrots becomes "8 g carrots"
newStr = quantity + " " + strOne.substring(quantity.length()) + " " + strTwo;
break;
} else if(strTwo.contains(quantity)) {
newStr = quantity + " " + strTwo.substring(quantity.length()) + " " + strOne;
break;
}
}
return newStr;
}
I hope this helps!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论