本位介绍了一种使用坐标进制的方法降多维数组降成一维数组的的方法,方法允许数组为任意维度,任意长度。修改方法即可不用递归的遍历多维数组。下面示例的是一种通用方法,可以降任意类型的高维数组降维或者遍历。
1. 定义高维数组的坐标,dims 为数组的维度信息
/**
* 多维数组的坐标
*
*/
public class MultiPoint {
//维度
private long[] dims = null;
//当前的索引(可理解为多维的坐标)
private long[] index = null;
//最大元素数量,等于 dims 的乘积
private long maxEleNum = 1;
//当前总的元素的索引
private long currNum = 0;
public MultiPoint(long[] dims) {
this.dims = dims;
index = new long[dims.length];
for(int i = 0; i < dims.length; i++) {
index[0] = 0;
maxEleNum *= dims[i];
}
}
/**
*
* @return
*/
public long getMaxEleNum() {
return maxEleNum;
}
/**
* 是否还有下一个坐标
* @return
*/
public boolean hasNext() {
return currNum < maxEleNum;
}
/**
* 获取下一个坐标点
* @return
*/
public long[] next() {
if(currNum == 0) {
currNum++;
return index;
}
for(int i = index.length - 1; i >= 0; i--) {
index[i]++;
if(index[i] >= dims[i]) {
index[i] = 0;
continue;
}else {
break;
}
}
currNum++;
return index;
}
}
2. 使用 Array 的 getLength 方法获取获取维度信息
/**
* 获取输入的多维数据的维度
* @param array
* @return
*/
private static long[] shape(Object array) {
long length = getArrayLength(array);
if(length <= 0) {
return null;
}
List<Long> tmp = new ArrayList<>();
while(length > 0) {
tmp.add((long) length);
array = Array.get(array, 0);
length = getArrayLength(array);
}
long[] ret = new long[tmp.size()];
for(int i = 0; i < ret.length; i++) {
ret[i] = tmp.get(i);
}
return ret;
}
/**
* 获取数组的长度
* @param obj
* @return
*/
private static long getArrayLength(Object obj) {
if(obj == null || !obj.getClass().isArray()) {
return -1;
}
return Array.getLength(obj);
}
3. 降维操作
/**
* 将高维数组降成一维数组
* @param array
* @param dims
* @return
*/
public static Object toSingleArray(Object array, long[] dims) {
MultiPoint tp = new MultiPoint(dims);
Object sample = array;
for(int i = 0; i < dims.length - 1; i++) {
sample = Array.get(sample, 0);
}
Object newArray = Array.newInstance(sample.getClass().getComponentType(), (int) tp.getMaxEleNum());
int index = 0;
while(tp.hasNext()) {
long[] point = tp.next();
Object tmp = array;
for(long p : point) {
tmp = Array.get(tmp, (int)p);
}
Array.set(newArray, index, tmp);
index++;
}
return newArray;
}