英文:
Java streams expression parse string to a double[m][n] (with n varying size)
问题
代码部分不要翻译,只返回翻译好的内容:
作为解析配置字符串的一部分,我想将一个字符串转换为双重[][]数组。配置字符串包含一个或多个(m)个三个或更多(n)个元素的集合。
对于输入:"0,0,0 | 500,0,10 | 0,300,20 | 500,300,30",
我期望得到输出:double[][]{{0,0,0},{500,0,10},{0,300,20},{500,300,30}}
下面的代码清单有效,但是,我想要改进代码如下(我正在努力实现这一点):
- 使代码通用,适用于可变数量的n元素,使其可以接受类似于*"0,0,0 | 500,0,10 | 0,300,20,999 | 500,300,30"*的输入,其中output[2] = [0,300,20,999]。我目前使用(
map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])})
),我想以通用方式重写它。 - 理想情况下,将这两个流表达式合并为一个表达式,在一次操作中从字符串获取并输出双重[m][n]。这可能吗?
代码清单:
String ss = "0,0,0 | 500,0,10 | 0,300,20 | 500,300,30";
System.out.println(ss);
String[][] result_s =
Arrays.
stream(ss.split("\\|")).
map(x -> x.trim().split(",")).
toArray(size -> new String[size][1]);
double[][] result_d =
Arrays.stream(result_s).
// 这下面一行是令人尴尬的部分,我想要使其通用化(不依赖元素数量)
map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])})
.toArray(size -> new double[size][1]);
double[][] result_new = Arrays.stream(ss.split("\\|")).collect(Collectors.toList(entry -> entry.x.trim().split(",")));
Arrays.
stream(ss.split("\\|")).
map(x -> x.trim().split(",")).
map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])}).
toArray(size -> new String[size][1]);
// 字符串数组
System.out.println("String arrays");
for(String[] rs : result_s) System.out.println(Arrays.toString(rs));
// 双重数组
System.out.println("Double arrays");
for(double[] rs : result_d) System.out.println(Arrays.toString(rs));
输出:
> 0,0,0 | 500,0,10 | 0,300,20 | 500,300,30<br>
> String arrays<br>
> [0, 0, 0]<br>
> [500, 0, 10]<br>
> [0, 300, 20]<br>
> [500, 300, 30]<br>
> Double arrays<br>
> [0.0, 0.0, 0.0]<br>
> [500.0, 0.0, 10.0]<br>
> [0.0, 300.0, 20.0]<br>
> [500.0, 300.0, 30.0]
英文:
As part of parsing a configuration string I would like to convert a string into a double[][] array. The configuration string contains one or more (m) sets of three or more (n) elements.
For the input: "0,0,0 | 500,0,10 | 0,300,20 | 500,300,30",
I would expect an output: double[][]{{0,0,0},{500,0,10},{0,300,20},{500,300,30}}
The listing below works, however, I would like to improve the code as follows (and I am having a hard time achieving that):
- Make the code generic, for a variable number of n-elements, such that it would accept an input such as "0,0,0 | 500,0,10 | 0,300,20,999 | 500,300,30", where the output[2] = [0,300,20,999]. I currently use (
map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])})
) which I want to rewrite generically. - Ideally combine the two stream expressions into one expression, taking in the string and outputting the double[m][n] in one go. Is this possible?
Listing:
String ss = "0,0,0 | 500,0,10 | 0,300,20 | 500,300,30";
System.out.println(ss);
String[][] result_s =
Arrays.
stream(ss.split("\\|")).
map(x -> x.trim().split(",")).
toArray(size -> new String[size][1]);
double[][] result_d =
Arrays.stream(result_s).
//This next line is the embarrassing part and I would like to make it generic (so independent of number of elements
map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])})
.toArray(size -> new double[size][1]);
double[][] result_new = Arrays.stream(ss.split("\\|")).collect(Collectors.toList(entry -> entry.x.trim().split(",")));
Arrays.
stream(ss.split("\\|")).
map(x -> x.trim().split(",")).
map(x -> new double[]{Double.parseDouble(x[0]),Double.parseDouble(x[1]),Double.parseDouble(x[2])}).
toArray(size -> new String[size][1]);
//Strings array
System.out.println("String arrays");
for(String[] rs : result_s) System.out.println(Arrays.toString(rs));
//double array
System.out.println("Double arrays");
for(double[] rs : result_d) System.out.println(Arrays.toString(rs));
Output :
> 0,0,0 | 500,0,10 | 0,300,20 | 500,300,30<br>
> String arrays<br>
> [0, 0, 0]<br>
> [500, 0, 10]<br>
> [0, 300, 20]<br>
> [500, 300, 30]<br>
> Double arrays<br>
> [0.0, 0.0, 0.0]<br>
> [500.0, 0.0, 10.0]<br>
> [0.0, 300.0, 20.0]<br>
> [500.0, 300.0, 30.0]
答案1
得分: 1
首先,对于"尴尬的行",您可以逐个流式处理每个x
,它是一个double[]
,并使用mapToDouble
:
.map(x -> Arrays.stream(x).mapToDouble(Double::parseDouble).toArray())
其次,这两个流可以非常简单地合并。在没有toArray(size -> new String[size][1])
的情况下,第一个流是Stream<String[]>
,这也是Arrays.stream(result_s)
生成的内容。
toArray
将流转换为数组,而Arrays.stream
将数组转换为流,因此Arrays.stream(result_s)
在某种程度上是在"撤销" toArray(size -> new String[size][1])
的操作。这两行代码可以互相抵消。
double[][] result_d =
Arrays.stream(ss.split("\\|"))
.map(x -> x.trim().split(","))
.map(x -> Arrays.stream(x).mapToDouble(Double::parseDouble).toArray())
.toArray(double[][]::new);
英文:
First, for the "embarrassing line", you can stream each x
, which is a double[]
, and mapToDouble
:
.map(x -> Arrays.stream(x).mapToDouble(Double::parseDouble).toArray())
Second, the two streams can be joined very simply. Without toArray(size -> new String[size][1])
, the first stream is Stream<String[]>
, which is also what Arrays.stream(result_s)
produces.
toArray
converts the stream to an array, while Arrays.stream
converts an array to a stream, so Arrays.stream(result_s)
is kind of undoing what toArray(size -> new String[size][1])
did. The two lines can cancel each other out.
double[][] result_d =
Arrays.stream(ss.split("\\|"))
.map(x -> x.trim().split(","))
.map(x -> Arrays.stream(x).mapToDouble(Double::parseDouble).toArray())
.toArray(double[][]::new);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论