java 在java中展平嵌套数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31851548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Flatten nested arrays in java
提问by mhGaber
I want to flatten nested arrays like:
我想展平嵌套数组,例如:
[[[1],2],[3]],4] -> [1,2,3,4]
manually in java I can't find a clue ! :S
在java中手动我找不到线索!:S
I have tried a manual java script guide but it doesn't get a solution
我已经尝试了手动 Java 脚本指南,但没有找到解决方案
回答by Holger
Java?8's Stream API offers a compact and flexible solution. Using the method
Java?8 的 Stream API 提供了一个紧凑而灵活的解决方案。使用方法
private static Stream<Object> flatten(Object[] array) {
return Arrays.stream(array)
.flatMap(o -> o instanceof Object[]? flatten((Object[])o): Stream.of(o));
}
you can perform the operation as
您可以执行操作
Object[] array = { 1, 2, new Object[]{ 3, 4, new Object[]{ 5 }, 6, 7 }, 8, 9, 10 };
System.out.println("original: "+Arrays.deepToString(array));
Object[] flat = flatten(array).toArray();
System.out.println("flat: "+Arrays.toString(flat));
or when you assume the leaf objects to be of a specific type:
或者当您假设叶对象为特定类型时:
int[] flatInt = flatten(array).mapToInt(Integer.class::cast).toArray();
System.out.println("flat int: "+Arrays.toString(flat));
回答by conorgriffin
I created a class to solve thisusing Java, the code is also shown below.
我创建了一个类来使用 Java解决这个问题,代码也如下所示。
Solution:
解决方案:
package com.conorgriffin.flattener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Flattens an array of arbitrarily nested arrays of integers into a flat array of integers.
* <p/>
* @author conorgriffin
*/
public class IntegerArrayFlattener {
/**
* Flatten an array of arbitrarily nested arrays of integers into a flat array of integers. e.g. [[1,2,[3]],4] -> [1,2,3,4].
*
* @param inputArray an array of Integers or nested arrays of Integers
* @return flattened array of Integers or null if input is null
* @throws IllegalArgumentException
*/
public static Integer[] flatten(Object[] inputArray) throws IllegalArgumentException {
if (inputArray == null) return null;
List<Integer> flatList = new ArrayList<Integer>();
for (Object element : inputArray) {
if (element instanceof Integer) {
flatList.add((Integer) element);
} else if (element instanceof Object[]) {
flatList.addAll(Arrays.asList(flatten((Object[]) element)));
} else {
throw new IllegalArgumentException("Input must be an array of Integers or nested arrays of Integers");
}
}
return flatList.toArray(new Integer[flatList.size()]);
}
}
Unit Tests:
单元测试:
package com.conorgriffin.flattener;
import org.junit.Assert;
import org.junit.Test;
/**
* Tests IntegerArrayFlattener
*/
public class IntegerArrayFlattenerTest {
Integer[] expectedArray = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
@Test
public void testNullReturnsNull() throws IllegalArgumentException {
Assert.assertNull(
"Testing a null argument",
IntegerArrayFlattener.flatten(null)
);
}
@Test
public void testEmptyArray() throws IllegalArgumentException {
Assert.assertArrayEquals(
"Testing an empty array",
new Integer[]{},
IntegerArrayFlattener.flatten(new Object[]{})
);
}
@Test
public void testFlatArray() throws IllegalArgumentException {
Assert.assertArrayEquals(
"Testing a flat array",
expectedArray,
IntegerArrayFlattener.flatten(new Object[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
);
}
@Test
public void testNestedArray() throws IllegalArgumentException {
Assert.assertArrayEquals(
"Testing nested array",
expectedArray,
IntegerArrayFlattener.flatten(new Object[]{1, 2, 3, 4, new Object[]{5, 6, 7, 8}, 9, 10})
);
}
@Test
public void testMultipleNestedArrays() throws IllegalArgumentException {
Assert.assertArrayEquals(
"Testing multiple nested arrays",
expectedArray,
IntegerArrayFlattener.flatten(new Object[]{1, 2, new Object[]{3, 4, new Object[]{5}, 6, 7}, 8, 9, 10})
);
}
@Test(expected = IllegalArgumentException.class)
public void throwsExceptionForObjectInArray() throws IllegalArgumentException {
IntegerArrayFlattener.flatten(
new Object[]{new Object()}
);
}
@Test(expected = IllegalArgumentException.class)
public void throwsExceptionForObjectInNestedArray() throws IllegalArgumentException {
IntegerArrayFlattener.flatten(
new Object[]{1, 2, new Object[]{3, new Object()}}
);
}
@Test(expected = IllegalArgumentException.class)
public void throwsExceptionForNullInArray() throws IllegalArgumentException {
IntegerArrayFlattener.flatten(
new Object[]{null}
);
}
@Test(expected = IllegalArgumentException.class)
public void throwsExceptionForNullInNestedArray() throws IllegalArgumentException {
IntegerArrayFlattener.flatten(
new Object[]{1, 2, new Object[]{3, null}}
);
}
}
回答by Gaurav Rai Mazra
It could be flattened by iterative approach.
它可以通过迭代方法扁平化。
static class ArrayHolder implements Iterator<Object> {
private final Object[] elements;
private int index = -1;
public ArrayHolder(final Object[] elements) {
this.elements = elements;
}
@Override
public boolean hasNext() {
return Objects.nonNull(elements) && ++index < elements.length;
}
@Override
public Object next() {
if (Objects.isNull(elements) || (index == -1 || index > elements.length))
throw new NoSuchElementException();
return elements[index];
}
}
private static boolean hasNext(ArrayHolder current) {
return Objects.nonNull(current) && current.hasNext();
}
private void flat(Object[] elements, List<Object> flattened) {
Deque<ArrayHolder> stack = new LinkedList<>();
stack.push(new ArrayHolder(elements));
ArrayHolder current = null;
while (hasNext(current)
|| (!stack.isEmpty() && hasNext(current = stack.pop()))) {
Object element = current.next();
if (Objects.nonNull(element) && element.getClass().isArray()) {
Object[] e = (Object[]) element;
stack.push(current);
stack.push(new ArrayHolder(e));
current = null;
} else {
flattened.add(element);
}
}
}
You can find the full source hereYou can use recursion to solve this problem.
你可以在这里找到完整的源代码 你可以使用递归来解决这个问题。
private void flat(Object[] elements, List<Object> flattened) {
for (Object element : elements)
{
if (Objects.nonNull(element) && element.getClass().isArray())
{
flat((Object[])element, flattened);
}
else
{
flattened.add(element);
}
}
}
Here is the link for recursion.
这是递归的链接。
回答by Renan Cidale
That's the way I would solve it. Don't know which kind of efficiency you are looking for. But yeah. that does the job in JavaScript.
这就是我要解决的方法。不知道你在找什么样的效率。但是是的。这在 JavaScript 中完成了这项工作。
arr.toString().split(',').filter((item) => item).map((item) => Number(item))
arr.toString().split(',').filter((item) => item).map((item) => Number(item))
A probably more efficient way to do this would be to use reduce and concat method from arr and recursion.
一种可能更有效的方法是使用来自 arr 和递归的 reduce 和 concat 方法。
function flattenDeep(arr1) {
return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}
回答by Alien
This is how I solved this problem in Java:
这就是我在 Java 中解决这个问题的方法:
public class ArrayUtil {
/**
* Utility to flatten an array of arbitrarily nested arrays of integers into
* a flat array of integers. e.g. [[1,2,[3]],4] -> [1,2,3,4]
* @param inputList
*/
public static Integer[] flattenArray(ArrayList<Object> inputList) {
ArrayList<Integer> flatten = new ArrayList<Integer>();
if (inputList.size() <= 0) {
return new Integer[0]; // if the inputList is empty, return an empty Integer[] array.
}
for (Object obj : inputList) {
recursiveFlatten(flatten, obj); // otherwise we can recursively flatten the input list.
}
Integer [] flatArray = new Integer[flatten.size()];
return flatArray = flatten.toArray(flatArray);
}
/**
* Recursively flatten a nested array.
* @param flatten
* @param o
*/
private static void recursiveFlatten(ArrayList<Integer> flatten, Object o){
if(isInteger(o)){ // if the object is of type Integer, just add it into the list.
flatten.add((Integer)o);
} else if(o instanceof ArrayList){ // otherwise, we need to call to recursively flatten the array
for(Object obj : (ArrayList<Object>) o){ // for the case where there are deeply nested arrays.
recursiveFlatten(flatten, obj);
}
}
}
/**
* Return true if object belongs to Integer class,
* else return false.
* @param obj
* @return
*/
private static boolean isInteger(Object obj) {
return obj instanceof Integer;
}
}
回答by Beniamin
you can try this code:
你可以试试这个代码:
String a = "[[[1],2],[3]],4] ";
a= a.replaceAll("[(\[|\])]", "");
String[] b = a.split(",");