Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

For example, I'd want to extract sub-arrays from an array like this, where arr is a 3-dimensional array, and "all" means that all possible values at that index position are selected:

getSubArray(arr, ["all","all",1]) returns a 2-dimensional slice of arr, with the indices from arr being ["all", "all", 1].

getSubArray(arr,["all",2,2]) should return a 1-dimensional array from arr, with the indices from arr being ["all", 2, 2].

share|improve this question
    
Unless the number of dimensions is variable, it's pretty straight-forward. –  RBarryYoung Jul 8 '13 at 21:19
    
I need to find a better title for this question: I'm trying to find a clear and unambiguous title, but I can't think of one. –  Anderson Green Jul 8 '13 at 21:24
    
The issues here are almost entirely language-inherent, they're not generally algorithmic issues. Declaring and implementing functions/methods that return arrays of variable dimensions is so language-specific that it's hard to even think of it in language-indepedent terms. Maybe try re-posting it as a request for a specific language? –  RBarryYoung Jul 8 '13 at 21:24
    
@RBarryYoung I think I could implement a language-specific algorithm to solve this problem without too much difficulty: the solution would likely be a simple recursive function that would take an array, a list of indices, and the current index position as input. I'll post a solution as soon as I've found it. –  Anderson Green Jul 8 '13 at 21:29
    
@RBarryYoung You said that the solution would be straightforward: which specific algorithm did you have in mind? –  Anderson Green Jul 8 '13 at 21:30
add comment

2 Answers

up vote 2 down vote accepted

One relatively simple way is to approach this task as a recursive mapping of K-tuples of dimension N to K-tuples of dimension M < N. Since this is language-agnostic, the following facilities need to be available in your target language:

  1. Given an instance of an N-dim array, find N
  2. Given an instance of an N-dim array and a k < N, find the number of items in dimension k
  3. Given an instance of an N-dim array A and a vector of N integers I, get or set the item at a position defined by indexes in the vector. For example, if the vector is I = {2, 3, 4}, there needs to be an operation for obtaining A[2, 3, 4] from the 3-D array A and a vector I.
  4. Given a vector D of size M defining dimensions, there needs to be an operation for constructing an array of M dimensions, each dimension taking the size of the corresponding item in the vector. For example, if the vector D = {3, 4}, there needs to be an operation that creates a 2-D array with dimensions 3 and 4.

Preprocess the request by constructing vectors F and D as follows:

  • For each "all" item at position i of the request, F[i] = -1 and D[i] = size(dimension[i])
  • For each numeric item k at position i of the request, F[i] = k and D[i] = 0.
  • Create an array for the result by taking all non-fixed indexes and passing them to the array constructor (prerequisite number four above).

Now your recursive procedure should look relatively straightforward:

void RecursiveCopy(Vector F, Vector D, Array S, Vector SI, int sp, Array T, Vector TI, int tp) {
    if (pos != TS.size) {
        if (F[sp] != -1) {
            // This is an "all" dimension
            for (int i = 0 ; i != D[sp] ; i++) {
                SI[sp] = i;
                TI[tp] = i;
                RecursiveCopy(F, D, S, SI, sp+1, T, TI, tp+1);
            }
        } else {
            // This is a fixed dimension
            SI[sp] = F[sp];
            RecursiveCopy(F, D, S, SI, sp+1, T, TI, tp);
        }
    } else {
        // Read from the source at indexes defined by vector SI
        var value = S.get(SI);
        // Write to the destination at indexes defined by vector TI
        T.setValue(TI, value); // Prerequisite 3
    }
}

Your getSubarray would look like this:

Array getSubarray(Array S, Vector<string> request) {
    Vector F = Vector[S.Size]; // The number of dimensions in A; prerequisite 1
    Vector D = Vector[S.Size]; // The number of dimensions in A
    Assert(request.Size == S.Size); // Request must have N items
    int k = 0;
    Vector resDim;
    for (int i = 0 ; i != req.Size ; i++) {
        if (req[i] == "all") {
            k++;
            F[i] = -1;
            D[i] = A.dimensionOf(i); // Prerequisite 2
            resDim.Add(D[i]);
        } else {
            F[i] = ParseInteger(req[i]);
            D[i] = -1;
        }
    }
    Array T = Array(resDim); // Prerequisite #4
    Vector SI = Vector[S.Size];
    Vector TI = Vector[k];
    RecursiveCopy(F, D, S, SI, 0, T, TI, 0);
    return T;
}
share|improve this answer
    
Is this solution written in pseudocode, or is it a specific programming language? –  Anderson Green Jul 8 '13 at 21:49
    
@AndersonGreen That's pseudocode that is using syntax similar to Java/C# and imaginary data types (e.g. all vectors would be 1-D arrays). A language-agnostic version is a lot harder than, say, a C# or Java version, though, because I would be able to write code instead of listing assumptions. –  dasblinkenlight Jul 8 '13 at 21:51
    
Using this function, which function call would correspond to getSubArray(arr, ["all","all",1])? –  Anderson Green Jul 8 '13 at 21:56
    
@AndersonGreen Take a look at the update - I added pseudocode for preprocessing and making the initial recursive call. –  dasblinkenlight Jul 8 '13 at 22:05
add comment

Even if the number of dimensions is variable, this seems fairly straightforward unless I am missing something?

It seems like you could just parse the second argument, find out what the dimension of the result should be, and then copy the data to the result. It's not hard to copy the data either because you could just find the length of a subarray of arr or if the language doesn't support it you could have the dimensions passed in as parameters.

share|improve this answer
    
Which data should be copied, specifically, and from which indices should it be copied? –  Anderson Green Jul 8 '13 at 21:31
    
Well, I imagine you should copy all the data from the indices which were not specified. In your second example, getSubArray(arr, ["all", 2, 2]) you would want to copy the values arr[i][2][2] for all valid i(which you can get by doing arr.length) Of course, implementing this is another deal altogether, but I don't think that is really language agnostic if you want the dimension of the array to be variable since at least for typed languages, you might have some trouble giving the parameters types –  Synderesis Jul 8 '13 at 21:46
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.