在java中展平嵌套数组

我想压扁嵌套数组,如:

[[[1],2],[3]],4] -> [1,2,3,4] 

在java中手动我找不到线索! :S

我尝试过手动java脚本指南,但它没有得到解决方案

我创建了一个使用Java 来解决这个问题的类 ,代码也如下所示。

解:

 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. * 

* @author conorgriffin */ public class IntegerArrayFlattener { /** * Flatten an array of arbitrarily nested arrays of integers into a flat array of integers. eg [[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 flatList = new ArrayList(); 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 testing:

 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}} ); } } 

Java 8的Stream API提供了紧凑而灵活的解决方案。 使用方法

 private static Stream flatten(Object[] array) { return Arrays.stream(array) .flatMap(o -> o instanceof Object[]? flatten((Object[])o): Stream.of(o)); } 

你可以执行操作

 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)); 

或者当您假定叶对象具有特定类型时:

 int[] flatInt = flatten(array).mapToInt(Integer.class::cast).toArray(); System.out.println("flat int: "+Arrays.toString(flat)); 

你可以试试这段代码:

 String a = "[[[1],2],[3]],4] "; a= a.replaceAll("[(\\[|\\])]", ""); String[] b = a.split(","); 

这就是我在Java中解决这个问题的方法:

 public class ArrayUtil { /** * Utility to flatten an array of arbitrarily nested arrays of integers into * a flat array of integers. eg [[1,2,[3]],4] -> [1,2,3,4] * @param inputList */ public static Integer[] flattenArray(ArrayList inputList) { ArrayList flatten = new ArrayList(); 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 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) 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; } } 

它可以通过迭代方法展平。

 static class ArrayHolder implements Iterator { 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 flattened) { Deque 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); } } } 

你可以在这里找到完整的源代码你可以使用递归来解决这个问题。

 private void flat(Object[] elements, List flattened) { for (Object element : elements) { if (Objects.nonNull(element) && element.getClass().isArray()) { flat((Object[])element, flattened); } else { flattened.add(element); } } } 

这是递归的链接。

这就是我解决它的方式。 不知道你在寻找哪种效率。 但是,是的。 在JavaScript中完成这项工作。

arr.toString().split(',').filter((item) => item).map((item) => Number(item))

一个可能更有效的方法是使用arr和递归的reduce和concat方法。

 function flattenDeep(arr1) { return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []); }