2016-07-26 11 views
0

Ich suche nach einer Möglichkeit, eine Reihe von Elementen in einem Array unbekannter Dimension (nicht Länge) zu lesen.Lesebereich von Werten in einem Array mit unbekannter Dimension

Der Client kann eine Leseanforderung für ein Objekt senden und den zu lesenden Bereich angeben. Die Eingabe String könnte wie folgt lauten: "1: 2: 3: 2,2: 3: 1: 4" zum Beispiel. Dies würde bedeuten, dass er die Elemente im Bereich von [1] [2] [3] [2] bis [2] [3] [1] [4] eines Arrays lesen möchte.

ein Betonelement lesen ich diese Funktion erstellt:

public Object readValue(Object obj,int[] positions) { 
    Object value = null; //Result 
    int objDimension = getDimension(obj); //Dimesion of the array 
    System.out.println("Dimension: " + objDimension); 
    try { 
     Object[] aux = (Object[]) obj; 
     for (int i = 0; i < objDimension - 1; i++) { 
      int pos = positions[i]; 
      aux = (Object[]) aux[pos]; 
     } 
     value = aux[positions[objDimension - 1]]; 
     System.out.println("Result: " + value); 
    } catch (ArrayIndexOutOfBoundsException e) { 
     // TODO: Send a fault to the client. 
     System.out.println("Error: "+e.getMessage()); 
    } 
    return value; 
} 

public static int getDimension(Object value) { 
    Class<?> clazz = value.getClass(); 
    String className = clazz.getName(); 
    int dimension = 0; 
    for (int i = 0; i < className.length(); i++) { 
     if (className.charAt(i) != '[') { 
      dimension = i; 
      break; 
     } 
    } 
    return dimension; 
} 


//Example. 
public static void main(String[] args) { 
    // TODO code application logic here 
    TestMultiDimensioNRead test = new TestMultiDimensioNRead(); 
    Integer[][][][] testSubject = new Integer[5][2][4][]; 

    testSubject[0][0][2] = new Integer[8]; 
    testSubject[0][0][0] = new Integer[15]; 
    testSubject[0][0][1] = new Integer[20]; 
    testSubject[0][0][3] = new Integer[2]; 
    testSubject[1][1][2] = new Integer[7]; 
    testSubject[1][1][2][0] = 80; 
    test.readValue(testSubject,new int[]{1, 1, 2, 0}); 
} 

Ich war eine gute Art und Weise denken kann das differens zwischen jeder Dimension Länge zu berechnen sein.

Wenn jemand mit einer guten Idee kommen kann, würde ich wirklich schätzen.

Vielen Dank im Voraus.

EDIT 1: Der Code in dieser Frage liest den Wert einer bestimmten Position in einem Array unbekannter Dimension. Mein Problem ist, alle Elemente zu lesen, die zwischen den angegebenen Punkten liegen. Dies war in der ersten Frage möglicherweise nicht klar.

+1

Dies ist wahrscheinlich aus vielen Gründen kein vorgeschlagener Ansatz. Kann ich fragen, was Sie insgesamt erreichen wollen? Ich würde wahrscheinlich überdenken, wie Sie das Problem lösen. – Kurtymckurt

+0

Es ist für einen Server, einer der Dienste ist es, eine Reihe von Werten aus einem Array beliebiger Größe zu lesen. Die Arrays sind nicht vordefiniert und haben keine Dimesion-Grenze (ich schrieb 255, wegen der Dimensionsbegrenzung von Java). Diese werden beim Start des Servers erstellt und stammen aus den Konfigurationsdateien. Übrigens ist jeder alternative Weg oder Idee willkommen, danke. – gabun88

+0

Können Sie die Dimensionen mit den Daten als Parameter übergeben? Es hat keinen Sinn, einen Algorithmus zu schreiben, um es herauszufinden, wenn der aufrufende Code es kennt (zumindest für diese Verwendung). – Kurtymckurt

Antwort

0

Den Weg gefunden, es zu tun, vielleicht ist es hilfreich bei jemandem für jemanden. Ich habe keine Prüfungen enthalten, das ist eher ein Testfall, um zu sehen, dass das funktioniert.

public class TestReadMultiDimensionArray { 

private int[] startPosition;    //Start position. 
private int[] endPosition;     //End position. 
private boolean inRange = false;   //If the current position is in range. 
private List<Object> result;    //List to store the values we find. 

public TestReadMultiDimensionArray() { 
    result = new ArrayList<>(); 
} 

public static void main(String[] args) { 
    TestReadMultiDimensionArray test = new TestReadMultiDimensionArray(); 
    Integer[][][][] testSubject = new Integer[2][2][4][]; 
    //(0,0,y,z) 
    testSubject[0][0][0] = new Integer[]{1};         //(0,0,0,0) 
    testSubject[0][0][1] = new Integer[]{2};         //(0,0,1,0) 
    testSubject[0][0][2] = new Integer[]{3};         //(0,0,2,0) 
    testSubject[0][0][3] = new Integer[]{4};         //(0,0,3,0) 
    //(0,1,y,z) 
    testSubject[0][1][0] = new Integer[]{5};         //(0,1,0,0) 
    testSubject[0][1][1] = new Integer[]{6};         //(0,1,1,0) 
    testSubject[0][1][2] = new Integer[]{7, 8, 9};        //(0,1,2,0) (0,1,2,1) (0,1,2,2) 
    testSubject[0][1][3] = new Integer[]{10};         //(0,1,3,0) 
    //(1,0,y,z) 
    testSubject[1][0][0] = new Integer[]{11, 12};        //(1,0,0,0).. 
    testSubject[1][0][1] = new Integer[]{13, 14, 15}; 
    testSubject[1][0][2] = new Integer[]{16, 17, 18}; 
    testSubject[1][0][3] = new Integer[]{19, 20, 21};       //..(1,0,3,2) 
    //(1,1,y,z) 
    testSubject[1][1][0] = new Integer[]{22, 23};        //(1,1,0,0).. 
    testSubject[1][1][1] = new Integer[]{24, 25, 26}; 
    testSubject[1][1][2] = new Integer[]{27, 28, 29, 30, 31, 32, 33, 34}; 
    testSubject[1][1][3] = new Integer[]{35, 36};        //..(1,1,3,1) 
    //Launch the test. 
    test.readValue(testSubject); 
} 

/** 
* 
* @param obj The Array from where we want to get the data. 
*/ 
public void readValue(Object obj) { 
    //Where should it start. 
    startPosition = new int[]{0, 1, 0, 0}; 
    //Where should it stop. 
    endPosition = new int[]{1, 1, 1, 2}; 
    System.out.println("Start Position:" + Arrays.toString(startPosition) + " End Position:" + Arrays.toString(endPosition)); 
    int[] currentPosition = new int[]{-1, -1, -1, -1}; 

    //Call to the method. 
    testRead((Object[]) obj, 0, currentPosition); 
    //Result to array. 
    Object[] arrayToReturn = result.toArray(new Object[0]); 
    System.out.println("Result: " + Arrays.toString(arrayToReturn)); 
} 

/** 
* Recursive method that looks for the values in a multi-dimensional array, in a given range. /!\ No checks are implemented here, wrong input can end in a 
* StackOverFlow. 
* 
* @param obj The array in Object[] form. 
* @param currentDimension The dimension we are currently in. 
* @param result The reference to the list that will store all the values we found. 
* @param currentPosition The current position we are in. 
*/ 
private void testRead(Object[] obj, int currentDimension, int[] currentPosition) { 
    for (int i = 0; i < obj.length; i++) { 
     currentPosition[currentDimension] = i; 
     if (Arrays.equals(startPosition, currentPosition) && currentDimension == (currentPosition.length - 1)) { 
      //Found the start position. 
      System.out.println("############ START ############"); 
      inRange = true; 
     } 

     if ((i >= startPosition[currentDimension] && i <= endPosition[currentDimension]) || inRange == true) { 
      //We are in the write track to get to the values we are looking for. 
      if (obj[i] instanceof Object[]) { 
       //The data contained in the cell is an array. 
       testRead((Object[]) obj[i], currentDimension + 1, currentPosition); 
      } else { 
       //The data contained in the cell is a scalar. This is what we where looking for. 
       System.out.println(Arrays.toString(currentPosition) + " Data: " + obj[i]); 
       result.add(obj[i]); 
      } 
     } 

     if (Arrays.equals(endPosition, currentPosition) && currentDimension == (currentPosition.length - 1)) { 
      //Found the end position. 
      System.out.println("############ END ############"); 
      inRange = false; 
     } 
    } 
} 

} 

Jede Frage oder Idee, den Code zu verbessern, ist willkommen.

1

Sie könnten eine rekursive Lösung verwenden:

public class Test { 
    private class TestMultiDimensioNRead { 
     public Integer readValue(Object testSubject, int[] coordinates) { 
      return readValue(testSubject, coordinates, 0); 
     } 

     private Integer readValue(Object testSubject, int[] coordinates, int which) { 
      if (testSubject instanceof Object[]) { 
       Object[] subject = (Object[]) testSubject; 
       if (coordinates.length > which + 1) { 
        return readValue(subject[coordinates[which]], coordinates, which + 1); 
       } else { 
        return (Integer) subject[coordinates[which]]; 
       } 
      } else { 
       // Throw some sort of exception? 
       return -1; 
      } 
     } 

     public Iterator<Integer> readValues(Object testSubject, int[] coordinates, int count) { 
      return readValues(testSubject, coordinates, count, 0); 
     } 

     private Iterator<Integer> readValues(Object testSubject, int[] coordinates, int count, int level) { 
      if (testSubject instanceof Object[]) { 
       Object[] subject = (Object[]) testSubject; 
       if (coordinates.length > level + 1) { 
        return readValues(subject[coordinates[level]], coordinates, count, level + 1); 
       } else { 
        return new Iterator<Integer>() { 
         int i = 0; 
         Integer[] intSubject = (Integer[]) subject; 

         @Override 
         public boolean hasNext() { 
          return i <= count; 
         } 

         @Override 
         public Integer next() { 
          return intSubject[coordinates[level] + (i++)]; 
         } 
        }; 
       } 
      } else { 
       // Throw some sort of exception? 
       return null; 
      } 
     } 

    } 

    public void test() { 
     TestMultiDimensioNRead test = new TestMultiDimensioNRead(); 
     Integer[][][][] testSubject = new Integer[5][2][4][]; 

     testSubject[0][0][2] = new Integer[8]; 
     testSubject[0][0][0] = new Integer[15]; 
     testSubject[0][0][1] = new Integer[20]; 
     testSubject[0][0][3] = new Integer[2]; 
     testSubject[1][1][2] = new Integer[7]; 
     testSubject[1][1][2][0] = 80; 
     testSubject[1][1][2][1] = 79; 
     testSubject[1][1][2][2] = 78; 
     Iterator<Integer> them = test.readValues(testSubject, new int[]{1, 1, 2, 0}, 3); 
     for (Integer x = them.next(); them.hasNext(); x = them.next()) { 
      System.out.println(x); 
     } 
     System.out.println(); 

    } 

    public static void main(String args[]) { 
     try { 
      new Test().test(); 
     } catch (Throwable t) { 
      t.printStackTrace(System.err); 
     } 
    } 
} 

Drucke 80 wie erwartet.

Es gibt wahrscheinlich mehr in Bezug auf die Überprüfung der Gesundheit zu tun, aber das scheint zu funktionieren.

+0

Ich sehe, was du meinst, aber wirklich ist das Problem, den Bereich zu lesen. Ich meine, der Bereich kann etwas wie folgt sein: Lesen von dem Element [0] [0] [0] [0] bis [4] [1] [1] [0]. Das heißt, Sie müssen alle Elemente lesen, die zwischen diesen beiden liegen. Das Ergebnis wäre ein Array mit allen Werten, die in diesem Bereich vorhanden sind. Ein einfaches Beispiel könnte sein: Lesen von [0] [0] [0] [0] bis [0] [0] [0] [5], dies wäre [0] [0] [0] [0], [0] [0] [0] [1], [0] [0] [0] [2], [0] [0] [0] [3], [0] [0] [0] [4 ] und [0] [0] [0] [5]. – gabun88

+0

@ gabun88 - Sie könnten das wahrscheinlich tun, indem Sie einen hastig konstruierten 'Iterator' auf der Ebene zurückgeben, auf der wir die korrekte Lokation finden, aber nur, wenn die Entfernung auf der tiefsten Ebene ist. Es wäre schwierig, etwas wie zum Beispiel "[0] [0] [0] [0] to [0] [0] [5] [5]" zu machen. – OldCurmudgeon

+0

@ gabun88 - Ich habe ein 'readValues' hinzugefügt, das einen' Iterator' zurückgibt - hoffe das hilft. – OldCurmudgeon

Verwandte Themen