在java中展平嵌套数组

在java中展平嵌套数组,java,arrays,algorithm,Java,Arrays,Algorithm,我想展平嵌套数组,如: [[[1],2],[3]],4] -> [1,2,3,4] 手动在java中我找不到线索!: 我尝试了一个手动java脚本指南,但没有找到解决方案您可以尝试以下代码: String a = "[[[1],2],[3]],4] "; a= a.replaceAll("[(\\[|\\])]", ""); String[] b = a.split(","); 我是用Java创建的,代码如下所示 解决方案: package com.conorgriffin.flat

我想展平嵌套数组,如:

[[[1],2],[3]],4] -> [1,2,3,4] 
手动在java中我找不到线索!:

我尝试了一个手动java脚本指南,但没有找到解决方案

您可以尝试以下代码:

String a = "[[[1],2],[3]],4] ";
a= a.replaceAll("[(\\[|\\])]", "");
String[] b = a.split(",");
我是用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.
 * <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()]);
    }
}

我就是这样用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;
    }

}
公共类ArrayUtil{
/**
*将任意嵌套的整数数组展平为
*整数的平面数组。例如[1,2,[3]],4]->[1,2,3,4]
*@param输入列表
*/
公共静态整数[]数组(ArrayList inputList){
ArrayList展平=新建ArrayList();

if(inputList.size()Java8的流API提供了一个紧凑而灵活的解决方案

private static Stream<Object> flatten(Object[] array) {
    return Arrays.stream(array)
                 .flatMap(o -> o instanceof Object[]? flatten((Object[])o): Stream.of(o));
}
或者假设叶对象为特定类型时:

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

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

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);
        }
    }
}
静态类ArrayHolder实现迭代器{
私有最终对象[]元素;
私有整数指数=-1;
公共阵列文件夹(最终对象[]元素){
这个元素=元素;
}
@凌驾
公共布尔hasNext(){
返回Objects.nonNull(elements)&&++indexelements.length))
抛出新的NoTouchElementException();
返回元素[索引];
}
}
私有静态布尔hasNext(ArrayHolder当前){
返回Objects.nonNull(current)和¤t.hasNext();
}
私有空心展开(对象[]元素,列表展开){
德克
您可以使用递归来解决这个问题

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);
        }
    }
}
private void flat(对象[]元素,列表展平){
for(对象元素:元素)
{
if(Objects.nonNull(element)&&element.getClass().isArray())
{
展开((对象[])元素,展开);
}
其他的
{
展平。添加(元素);
}
}
}

这是的链接。

这是我解决问题的方法。 我不知道你想要的是哪种效率。但是,是的,这在JavaScript中就行了

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

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

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

如果它是只有两个级别的基元数组,则可以执行以下操作:

Arrays.stream(array)
  .flatMapToInt(o -> Arrays.stream(o))
  .toArray()

获取相应的装箱数组(如有必要,可以取消装箱)

这是一个javascript问题。这在Java中没有意义。我想用任何语言来解决它,Java或javascriptwe真的很想帮助,但我不明白你的要求。cn你给出了一个Java输入和所需输出的示例?但在Java中解决这一问题的方法与在javascript中完全不同……Java真的吗es没有混合类型数组(其中一个项可以是
int
int[]
)。它有
List
对象…OP有数组,而不是字符串,您返回的是字符串而不是数组。遗憾的是,如果内部数组是像int[]这样的基元类型,则这不起作用,因为
o instanceof Object[]
检查失败,无法将基元数组转换为对象数组。@DQQpy对于基元数组,不需要递归,因为基元数组不能包含数组,所以可以使用
.flatMap(o->o instanceof int[]?arrays.stream((int[])o.boxed():o instanceof object[]?展平((object[])o:stream of(o))
或者,要始终映射到
int
值,
公共静态IntStream flattoint(Object o){return o instanceof int[]?数组.stream((int[])o:o instanceof Object[]?Arrays.stream((Object[])o.flatMapToInt(x->flattoint(x)):IntStream of((Number)o.intValue());}
如果输入类型是一个像
int[][]][]
这样的常规数组,操作会更简单,因为不需要递归,您只需要n-1
flatMap
n维的步骤,
静态IntStream展平(int[][][]array){返回Arrays.stream(array.flatMap(Arrays::stream).flatMap(Arrays::stream).flatMapToInt(Arrays::stream);}
很好,但是如果内部数组是混合类型,那么所有大小写差异都会变得非常复杂。我找不到更好的解决方案though@DQQpy如果愿意,您可以使用
java.lang.reflect.array
通用地处理所有数组类型:
static Stream flant(Object o){return o!=null&&o.getClass().isArray()?IntStream.range(0,Array.getLength(o)).mapToObj(ix->Array.get(o,ix)).flatMap(x->flatte(x)):Stream.of(o);}
您只需执行
Array.flatte(无穷大)
,它要短得多。
function flattenDeep(arr1) {
   return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}
Arrays.stream(array)
  .flatMapToInt(o -> Arrays.stream(o))
  .toArray()