Как транспонировать список <List>? - PullRequest
13 голосов
/ 31 мая 2010

У меня есть следующий ArrayList,

[Title,Data1,Data2,Data3]
[A,2,3,4]
[B,3,5,7]

И я хотел бы преобразовать этот как

[Title,A,B]
[Data1,2,3]
[Data2,3,5]
[Data3,4,7]

Я немного запутался с подходом. Любая подсказка будет высоко ценится.

Спасибо.

Ответы [ 11 ]

13 голосов
/ 31 мая 2010

Это называется транспозицией. Следующий фрагмент делает то, что вам нужно:

import java.util.*;
public class ListTranspose {
    public static void main(String[] args) {
        Object[][] data = {
            { "Title", "Data1", "Data2", "Data3" },
            { "A", 2, 3, 4 },
            { "B", 3, 5, 7 },
        };
        List<List<Object>> table = new ArrayList<List<Object>>();
        for (Object[] row : data) {
            table.add(Arrays.asList(row));
        }
        System.out.println(table); //  [[Title, Data1, Data2, Data3],
                                   //   [A, 2, 3, 4],
                                   //   [B, 3, 5, 7]]"
        table = transpose(table);
        System.out.println(table); //  [[Title, A, B],
                                   //   [Data1, 2, 3],
                                   //   [Data2, 3, 5],
                                   //   [Data3, 4, 7]]
    }
    static <T> List<List<T>> transpose(List<List<T>> table) {
        List<List<T>> ret = new ArrayList<List<T>>();
        final int N = table.get(0).size();
        for (int i = 0; i < N; i++) {
            List<T> col = new ArrayList<T>();
            for (List<T> row : table) {
                col.add(row.get(i));
            }
            ret.add(col);
        }
        return ret;
    }
}

Смотри также

4 голосов
/ 03 августа 2017

Вот мое решение. Спасибо коду @ jpaugh. Надеюсь, это поможет вам. ^ _ ^

public static <T> List<List<T>> transpose(List<List<T>> list) {
   final int N = list.stream().mapToInt(l -> l.size()).max().orElse(-1);
   List<Iterator<T>> iterList = list.stream().map(it->it.iterator()).collect(Collectors.toList());
   return IntStream.range(0, N)
       .mapToObj(n -> iterList.stream()
       .filter(it -> it.hasNext())
       .map(m -> m.next())
       .collect(Collectors.toList()))
   .collect(Collectors.toList());
}
2 голосов
/ 31 мая 2010

Техника называется транспонированием. Пример реализации.

public static MyObject [][] transpose(MyObject [][] m){
    int r = m.length;
    int c = m[r].length;
    MyObject [][] t = new MyObject[c][r];
    for(int i = 0; i < r; ++i){
        for(int j = 0; j < c; ++j){
            t[j][i] = m[i][j];
        }
    }
    return t;
}
2 голосов
/ 31 мая 2010

Математика позади: вам нужно транспонировать матрицу. Это проще, если вы используете 2-мерный массив или «Список списков», что в значительной степени совпадает с коллекциями. Список массивов тоже работает, но он немного более запутанный.

В этой статье в Википедии показаны некоторые алгоритмы для транспонирования.

2 голосов
/ 31 мая 2010

как то так может быть

List<List<String>> list = new ArrayList<List<String>>(firstList.size());
for(int i = 0; i < firstList.size(); i++) {
   list.add(Arrays.asList(
      firstList.get(i),
      secondList.get(i),
      thirdList.get(i))
   );
}
2 голосов
/ 31 мая 2010

Это называется операцией транспонирования. Пример кода здесь , но потребует значительных изменений, поскольку у вас есть ArrayList of Arrays (что я понимаю из вашего вопроса)

1 голос
/ 31 мая 2010

Если это задача переноса данных, вы можете рассмотреть удобную электронную таблицу, если ее размер не слишком велик.

Для работы с матрицами существует библиотека jScience, которая поддерживает матрицу. Для простого переноса метрики это было бы излишним, но это зависит от того, что нужно с ним сделать.

1 голос
/ 31 мая 2010

У вас есть фиксированное количество ArrayLists и они имеют фиксированный размер для начала? Если это исправлено, вы можете получить значение индекса int и обработать каждый ArrayList по очереди в одном и том же цикле. Затем вы можете перенести каждое значение во временный ArrayList и затем поместить ссылку на него в окончательный ArrayList для вывода.

Звучит запутанно? Вот примерное решение:

ArrayList tempList = new ArrayList();
ArrayList outputList = new ArrayList();

for(index=0;index<list1.getsize();index++){
// Add null checks and other validation here
tempList.add( list1.get(index) );
tempList.add( list2.get(index) );
tempList.add( list3.get(index) );
outputList.add( tempList );
}
1 голос
/ 31 мая 2010

Проверьте, все ли списки имеют одинаковый размер.

Поместите информацию в матрицу (например, список с элементами списка), чтобы получить количество списков и размер списка.

Создайте новую матрицу с повернутой информацией о размере. (От 3х4 до 4х3)

Реализация 2 Для циклов и размещение элементов в новой матрице.

1 голос
/ 31 мая 2010

Вам нужно использовать двумерный массив. Смотрите здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...