Hi there!

What I'm trying to do is have multiple lists have the same length (size) so I can iterate easily over them later.

I want to "extend" the size of the smaller lists to match that of the largest list without just tacking on entries, I want to distribute the data.

I've been trying for hours now (at least 7) and can't quite get it.

(if it helps, they are ArrayList<Double>)

Any help is appreciated.

-- Turt2Live

Recommended Answers

All 15 Replies

You need to explain more in detail about "distribute data" because that is wide topic

Provide an example: eg I have an array {1,2,3} that needs to be "extended" to length 8. What should the result look like?

Also, when you say distribute data, how do you handle duplicated item in these lists? Do you want to clone the list items? For example, an array of {1,2,3} is the smaller list and {1,4,7,8,9} is the larger one. What would be the result?

I would have something like so:

a list with the contents {1, 1, 2, 1, 1} expanded to 10 elements would look like this:

{0.5, 0.5, 0.5, 0.5, 1, 1, 0.5, 0.5, 0.5, 0.5}.

Basically the data would follow the same "curve" (if you were to graph it), but the data itself is extended over a larger index.

If the data are related to each other you should write custom object and place this in ArrayList or whatever you wish to use

public class MyNumbers{

  private int a;
  private double d;

  public MyNumbers(int a, double d){
    this.a = a;
    this.d = d;
  }

 //some setter and getters or any other methods 
}

So you can do stuff like this

MyNumber num = new MyNumber(1, 0.5);
List<MyNumber> list = new ArrayList<MyNumber>();
list.add(num);

You example has the expanded array an integer multiple of the size of the input. I gueaa that's not always the case.
There's a simple approach that I have seen used to spread accounting data (eg sales) from a weekly source to a calendar monthly output or v.v. (and all kinds of other overlapping time frames). I think it's the same problem?

If you have an array size n that you want to expand to size m like you said, then logically you could:
create an array of size n*m
populate it from the first array by dividing each entry by m and adding that to the next m positions
sum the array by summing each block of n entries to give an result of size m

Obviously that array could be large, but logically it's not really needed; you could achieve exactly the same result with acouple of nested loops that I don't have time to work out right now.

Update:
I've now had a chance to think about the loop version (no n*m array).
Yes, it works really well, <20 lines of code, and just a single loop.
Give it a try. I won't sspoil your fun by posting the solution, at least not before you've had a go!
J

The issue is that the data (always doubles) may not be the same, and the maximum size can differ, as well as the size of the array I want to expand can differ.

I know that I could apply a "z-score" method to the data, if only it wasn't possible for it to "rise" and "lower" multiple times in the array (like {1, 2, 1, 2, 1}).

OK, just a simple thought here. Have you tried ArrayList class to keep the dynamic value? The class can insert and/or remove elements at any index. The only thing you need to keep an eye on is the class takes only Object, not primitive. Still you could use a class that matches the primitive type you want... Just my two cents.

There is an object for the primatives, eg: Double.

And it wouldn't be that hard to add filler to the ArrayList, but that's not what I want.

I guess I'll come up with something

The method I suggested works for input & output arrays of any (sensible) size - no need for one to be a multiple of the other.
It's my birthday (really), so here's a gift...

 double[] spread(double[] in, int outSize) {
      // Algorithm is equivalent to:
      // If you have an array size n that you want to change to size m
      // by distributing the values, then logically you can:
      // 1. create an array of size n*m
      // 2. populate it from the first array by dividing each entry by m and 
      //    writing that to the next m positions
      // 3. sum the array by summing each block of n entries to give 
      //    a result of size m
      // This version is coded for clarity rather then performance.

      double[] out = new double[outSize];
      int inSize = in.length;
      int inIndex = 0, outIndex = 0, inCount = 0, outCount = 0;
      double temp = 0;
      for (int i = 0; i < inSize * outSize; i++) {
         temp += in[inIndex] / outSize;
         if (++inCount >= outSize) {
            inIndex++;
            inCount = 0;
         }
         if (++outCount >= inSize) {
            out[outIndex] = temp;
            temp = 0;
            outIndex++;
            outCount = 0;
         }
      }
      return out;
   }

Use something like this to test it:

   public void run() {

      double[] data = { 1, 2, 3, 2, 1 };

      System.out.println("Input: " + Arrays.toString(data));
      double temp = 0;
      for (int i = 0; i < data.length; i++)
         temp += data[i];
      System.out.println("Total of input array is " + temp);

      double[] result = spread(data, 8);

      System.out.println("Output = " + Arrays.toString(result));
      temp = 0;
      for (int i = 0; i < result.length; i++)
         temp += result[i];
      System.out.println("Total of output array is " + temp);
   }

There is an object for the primatives, eg: Double.

And it wouldn't be that hard to add filler to the ArrayList, but that's not what I want.

Sorry, my suggestion is only about data structure you may want to use, not the algorithm for spreading your array. There are different ways to do that. I see one problem for spreading and you need to think about it because you are trying to convert continueous to discrete. Do you ever have to expand array size that is not a multiplication of an integer? If so, what would a result of array {1, 2, 1, 1} to be expanded to size of 7?

@James, happy Birthday ;) You gave him one example of how to expand it and that what I did with one of my mini project. Not sure what he wants though...

Thank you :)
Yes, we're having guess what the OP wants for non-integer size multiples. Are you there @turt2live?

ps: is this what is required?

Data is 4 elements
 1.00  2.00  1.00  1.00 
total is  5.00
Result is 7 elements
 0.57  0.71  1.14  0.86  0.57  0.57  0.57 
total is  5.00

Happy birthday, and yes, that's exactly what I want (sorry for being unable to explain it)

Thanks for the code, but I won't be copy/pasting it in, much easier to learn what you did rather then paste and leave it there.

OK, excellent!
Yes, please use that code for study and inspiration, then write your own better version. If you get stuck I'll be happy to explain, but if you keep the imaginary n*m array in mind, and grok the variable names, it shoudn't be too hard.
J

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.