如何为数组的“ n”个维度循环?

时间:2019-10-12 21:32:51

标签: java arrays for-loop

我正在尝试创建一种方法,该方法将汇总潜在项目并从数组中返回该总和。以下是一些预期的示例输入:

arraySum(new int[10]); // 10
arraySum(new int[2][5]); // 10
arraySum(new int[5][5][5]); // 125

问题是我实际上无法知道我正在处理多少个尺寸。到目前为止,我发现在数组上调用String.valueOf(array)会返回一个包含[字符的字符串,无论数组中存在许多维,

String.valueOf(new int[10]); // [I@hash_code
String.valueOf(new int[5][2]); // [[I@hash_code
String.valueOf(new int[5][5][5]); // [[[I@hash_code

我可以通过执行String.valueOf(array).split("\\[").length - 1来找出该数组存在的确切维数。我不确定从这一点上我能做什么。

public int arraySum(final Object array) {
    checkArgument(array.getClass().isArray()); // from com.google.common.base.Preconditions
    final int dimensions = String.valueOf(array).split("\\[").length - 1;
    int sum = 0;

    // somehow loop n-times over here to count up

    return sum;
}

通常,在多维数组上进行迭代时,彼此之间会有多个循环,但是在我的情况下,我将需要n循环,而我显然不能对其进行硬编码。我该怎么办?

2 个答案:

答案 0 :(得分:1)

这样做:

//on page load, check localStorage value
var stylesheet = document.createElement('link');
stylesheet.rel = "stylesheet";
  

if(localStorage.getItem('nightMode') == "ON") {
  //add link to night mode CSS
  stylesheet.href = "path/to/nightmode.css";
  document.getElementsByTagName('head')[0].appendChild(stylesheet);
}
else {
  //add link to night mode CSS
  link.href = "path/to/normalmode.css";
  document.getElementsByTagName('head')[0].appendChild(stylesheet);
}

//set the nightmode at some point by calling this function
function toggleNightMode() {
  var currentMode = localStorage.getItem('nightMode');
  if(!currentMode) {
    //the vaeriable is not set, set it to default value
    localStorage.setItem("nightMode", "OFF");
  }
  else if(currentMode == "ON") {
    //current mode is ON, now set it to OFF
    localStorage.setItem("nightMode", "OFF");
  }
  else {
    //set to ON
    localStorage.setItem("nightMode", "ON");
  }
}

您还可以为基本数组重载此方法。这是我如何以最少的代码重复做到这一点:

public static int arraySum(final Object[] array) {
    if(array.length == 0) return 0;
    return array.length * ((array[0] instanceof Object[]) ? arraySum((Object[]) array[0]) : 1);
}

如果子数组的长度可能不相等,则应使用加法而不是乘法:

private static int doArraySum(Object array) {
    if(array == null || !array.getClass().isArray()) return 1;
    int length = Array.getLength(array);
    if(length == 0) return 0;
    return length * doArraySum(Array.get(array, 0));
}

public static int arraySum(Object[] array) {
    return doArraySum(array);
}

public static int arraySum(int[] array) {
    return doArraySum(array);
}

// other primitives

示例:

private static int doArraySum(Object array) {
    if (array == null || !array.getClass().isArray()) return 1;
    return IntStream
            .range(0, Array.getLength(array))
            .map(i -> doArraySum(Array.get(array, i)))
            .sum();
}

答案 1 :(得分:0)

我的解决方案是使用for循环迭代尺寸并执行长度的乘法:

public int arraySum(Object array) {
    int count = 1;      // necessary to prevent initial 0 multiplication
    int dim = ...;      // the dimensions of the array

    for (int i = 0; i < dim; ++i) {
        int len = Array.getLength(array);
        count *= len;

        if (len == 0) {
            break; // a length of 0 at any point means no potential items
        }

        array = Array.get(array, 0); // never fails, since len must be greater than 1 by this point
    }
}

这给了我潜在的长度,或者说是数组容纳特定类型的能力。

arraySum(new int[10]);          // 1 array with 10 ints, capacity 10 * 1 == 10
arraySum(new float[10][2]);     // 2 arrays with 10 floats, capacity of 2 * 10 == 20
arraySum(new CustomType[5][5]); // 5 arrays with 5 custom types, capacity 5 * 5 == 25