Kr Neki
Kr Neki

Reputation: 95

Populating 2D array with two 1D arrays with for loop

I have to make two dimensional array out of two one dimensional array so that first row is filled with data from arrayCentri. All the other rows are filled with arrayTocke. Number of Colums is arrayCentri.length(number of elements in arrayCentri decide number of colums) and number of rows should be (arrayTocke.length/arrayCentri.length) +1 (because first row is data from arrayCentri). Columns of array will represent clusters. First element of the colum will be the center of cluster an all the others elements of colum will be points of cluster.

My idea was to do it with for loops, so that i iterate thru both arrays arrayCentri and arrayTocke and thru clusterji but I don't get it...

public static void main(String[] args) {
    String[] arrayCentri= {"center1","center2","center3"};
    String[] arrayTocke= {"tocka1","tocka2","tocka3","tocka4","tocka5","tocka6","tocka7","tocka8","tocka9", "tocka10"};
    String[][] clusterji = new String[((arrayTocke.length/arrayCentri.length) +1)][arrayCentri.length]; 

    for (int col = 0; col < clusterji.length; col++) {
        for (int row = 0; row < clusterji[0].length; row++) { // why clusterji[0].length? //
            for(int i=0; i< arrayCentri.length; i++) {
                for (int j=0; j< arrayTocke.length; j++) {
            clusterji[0][row]= arrayCentri[i]; // First row is filled with array centri //
            clusterji[1][0]= arrayTocke[j]; // From second row there should be filled with arrayTocke //

       }
      }
     }
    }

for(int i=0; i<clusterji.length; i++)
{
    for(int j=0; j<clusterji[0].length; j++)
        System.out.print(clusterji[i][j]+ " ");
    System.out.println();

}
}

 }

The result is:

center3 center3 center3 
tocka10 null null 
null null null 
null null null 

I get the number of columns right but the rows and data not. Should look like this:

center1 center2 center3
tocka1 tocka2 tocka3
tocka4 tocka5 tocka6
tocka7 tocka8 tocka9
tocka10

So where am I getting it wrong?

Upvotes: 0

Views: 810

Answers (2)

Sven
Sven

Reputation: 952

I think you are over complicating this task. You can map the arrays into Lists and use the List APIs to make less code for the same task. And if you drag in Guava or Apache Commons, either one, they both have support for partitioning a list into many lists, exactly what you want to do.

Here are two examples. First is using plain Java API and array copying. The second is using Guava's partition.


package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
import com.google.common.collect.Lists;

public class ArrayTest {

  @Test
  public void twoArrayCopyRangeTest() {

    String[] centri = {"center1","center2","center3"};
    String[] tocke = {"tocka1","tocka2","tocka3","tocka4","tocka5","tocka6","tocka7","tocka8","tocka9", "tocka10"};
    List<String[]> splitList =  new ArrayList<>();
    splitList.add(centri);
    int splitIndex = 0;

    while (splitIndex < tocke.length) {
      splitList.add(Arrays.copyOfRange(tocke, splitIndex, centri.length + splitIndex));
      splitIndex = splitIndex + centri.length;
    }

    splitList.forEach(l -> {
      System.out.println(Arrays.stream(l).collect(Collectors.joining(",")));
     });

  }

  @Test
  public void twoArrayPartitionTest() {

    String[] centri = {"center1","center2","center3"};
    String[] tocke = {"tocka1","tocka2","tocka3","tocka4","tocka5","tocka6","tocka7","tocka8","tocka9", "tocka10"};

    List<String> splitList =  new ArrayList<>();
    splitList.addAll(Arrays.asList(centri));
    splitList.addAll(Arrays.asList(tocke));

    List<List<String>> partition = Lists.partition(splitList, centri.length);
    partition.forEach(l -> System.out.println(l.stream().collect(Collectors.joining(":"))));

  }
}


Upvotes: 1

Eritrean
Eritrean

Reputation: 16508

I would suggest to copy every three strings from your arrayTocke and populate the rows of your 2D array using Array.copyOfRange(originalArray, int from, int to)

public static void main(String[] args) {
    String[] arrayCentri= {"center1","center2","center3"};
    String[] arrayTocke= {"tocka1","tocka2","tocka3","tocka4","tocka5","tocka6","tocka7","tocka8","tocka9", "tocka10"};

    int rows     = arrayTocke.length/arrayCentri.length + (arrayTocke.length%arrayCentri.length == 0 ? 1 : 2);
    int columns  = arrayCentri.length;
    int rowCount = 0;

    String[][] clusterji  = new String[rows][columns];
    clusterji[rowCount++] = arrayCentri;
    for(int i=0;i < arrayTocke.length; i += columns){
        clusterji[rowCount++] = Arrays.copyOfRange(arrayTocke, i, Math.min(arrayTocke.length,i+columns));
    } 
    Arrays.stream(clusterji).forEach(row->{System.out.println(Arrays.toString(row));});
}

OR

Using Streams

    public static void main(String[] args) {
    String[] arrayCentri= {"center1","center2","center3"};
    String[] arrayTocke= {"tocka1","tocka2","tocka3","tocka4","tocka5","tocka6","tocka7","tocka8","tocka9", "tocka10"};
    //concat both arrays to one to get {"center1","center2","center3","tocka1","tocka2" ..."tocka10"}
    String[] centriAndTocke = Stream.concat(Arrays.stream(arrayCentri), Arrays.stream(arrayTocke)).toArray(String[]::new);

    int columns  = arrayCentri.length;        
    String[][] clusterji = IntStream.iterate(0, i -> i + columns)
                                .limit((long) Math.ceil((double) centriAndTocke.length / columns))
                                .mapToObj(j -> Arrays.copyOfRange(centriAndTocke, j, Math.min(centriAndTocke.length, j+columns)))
                                .toArray(String[][]::new);        
    Arrays.stream(clusterji).forEach(row->{System.out.println(Arrays.toString(row));});
}

Upvotes: 1

Related Questions