2

I am trying to write a method in java to search for an item in an array and output the indices. However, I would like it to work on arrays of different dimensions. Since I have to declare the input type as for example String[][], I can't pass a String[] as argument.

An example of what I want to achieve:

int[][] my_array1 = {{1, 2}, {3, 4}};
int[] my_array2 = {5,6};

int item1 = 2;
int item2 = 5;

search_item(my_array1, item1);
search_item(my_array2, item2);

Output:

"Index of item1:" [0][1]
"Index of item2:" [0]

I have no idea how this could be done. I tried to work with generic arrays which did not work so far.

Thank you in advance.

  • you could probably use `instanceof` and reflection – Lino Mar 01 '19 at 11:06
  • If the array's dimension can only be 1 or 2, you could just write two separate methods. If it could be of higher dimension, recursion could work. – assylias Mar 01 '19 at 11:14
  • Thank you for your answers. Until this point I am not working with arrays of higher order than 2 but I would like to work in one method, also because I'm interested in general how to tackle this problem. Would you be so kind to post a small example. I am not that familiar with recursion other than the benchmark examples of calculating factorials etc. I'm also fully aware of how to get instanceof and reflection to work. – F Rooyackers Mar 01 '19 at 11:18

2 Answers2

3

Here's a sketch of recursive solution:

public List<String> findArrayMatches(Object [] input, String pattern) {
  List<String> matchingIndices = new ArrayList<>();
  for (int i = 0; i < input.length; i++) {
    Object elem = input[i];
    if (elem instanceof String) {
      String elemString = (String)elem;
      // check if elemString matches pattern and add index to matchingIndices if it does
    } else if (elem instanceof Object[]) {
      Object [] elemArray = (Object[])elem;
      //recursive call here
      List<String> matchingSublevel = findArrayMatches(elemArray, pattern);
      //prepend current index to all items of matchingSublevel and add to matchingIndices
    } else {
      throw new IllegalArgumentException("input is not an array of strings or arrays");
    }
  }
  return matchingIndices;
}

A few notes about this code:

  1. As you can see, there is no way for the compiler to check that your input array contains only elements you want to allow, you have to do that check at runtime
  2. Everything relies on the fact that (in Java) multi-dimensional arrays are just arrays whose elements are also arrays.
  3. This code also handles "wonky" multi-dimensional arrays, i.e. where you get a mixture of strings and arrays on the same level
  4. Another important feature this solution relies on is the covariance of arrays, that is that any array is instanceof Object[]. This would not be the case with generics, and it would cause a problem if you were trying to insert new elements into the input array. Luckily you don't.
  5. When I said "any array" in the previous point, that isn't entirely true. It's any array that isn't an array of primitives, so it'd work with String[] but not with int[]. I'll leave it to you to work out how to make it work with int[], as it could be fiddly but adds very little to the basic principle.
biziclop
  • 48,926
  • 12
  • 77
  • 104
1

Something like this should work. This is somehow nasty, returning a String, but I guess you get the idea. Also, note that only first coincidence will be thrown.

The first call to the method has nRow as 0. --> checkPosition(0, valueToCheck);

public String checkPosition(int nRow, int valueToCheck)  
{
    if(nRow>= array.length) 
       return "";
    List<Integer> rowvalues = Arrays.asList(Arrays.asList(array).get(nRow));
    if(rowvalues.contains(valueToCheck))
    {
        String result = "["+nRow+"]["+rowvalues.indexOf(valueToCheck)+"]";
        if (!array.getClass().getComponentType().isArray())
             result= result.substring(result.indexOf("["), result.lastIndexOf("["));
        return result;
     }

  return checkPosition(nRow+1, valueToCheck);
}

Examples:

(check 0,5)

  • 1 dimension - array: [0,1,0,5,0] | output: [3]
  • 2 dimensions - array: [0[0,5,0,0,0],0,0,0,0] | output: [0][1]
aran
  • 10,978
  • 5
  • 39
  • 69