Создание комбинаций из нескольких столбцов в объект массива, состоящий из комбинации значений и имени столбца в java?

#java #data-structures #java-8

#java #структуры данных #java-8

Вопрос:

Создание комбинаций из нескольких столбцов в объект массива, состоящий из комбинации значений и имени столбца в java? Так что каждый объект будет состоять из массива Object (column name, value) .

У меня есть информация, хранящаяся по имени столбца и значениям внутри этого столбца. Например:

 Region  Store       State
west    Reliance    california
east    Dmart       newyork
  

В основном для приведенного выше структура JSON выглядит следующим образом

 [
  {
    "type": "Region",
    //more fields
    "filterValues": [
      {
        "name": "west"
        //more fields
      },
      {
        "name": "east"
      }
    ]
  },
  {
    "type": "Store",
    "filterValues": [
      {
        "name": "Reliance"
      },
      {
        "name": "Dmart"
      }
    ]
  },
  {
    "type": "State",
    "filterValues": [
      {
        "name": "california"
      },
      {
        "name": "newyork"
      }
    ]
  }
]
  

Как я могу преобразовать приведенную выше структуру в следующие комбинации:

 Region west  | Store Reliance | State california
Region west  | Store Reliance | State newyork
Region west  | Store Dmart    | State california
Region west  | Store Dmart    | State newyork
.
.
.
  

Таким образом, структура объекта будет следующей.

 [
  {
    "values": [
      {
        "type": "Region",
        "name": "west"
      },
      {
        "type": "Store",
        "name": "Reliance"
      },
      {
        "type": "State",
        "name": "california"
      }
    ]
  },
  {
    "values": [
      {
        "type": "Region",
        "name": "west"
      },
      {
        "type": "Store",
        "name": "Reliance"
      },
      {
        "type": "State",
        "name": "newyork"
      }
    ]
  }
]
  

Как я могу реализовать эту структуру данных?
Я пытался сначала создать map, в котором имя столбца будет key , а значения в этом столбце будут частью value as

 Map<String, List<String>> typeBOsMap = attributes
                        .stream()
                        .collect(Collectors.toMap(Attribute::getType,
                                attribute -> attribute.getFilterValues()
                                        .stream()
                                        .map(AttributeFilters::getFilterValue)
                                        .collect(Collectors.toList()))
                        );
  

Но после этого я снова застрял на том, как комбинация будет создана из этой карты?


Комментарии:

1. всегда существует три типа или может быть несколько?

2. Может быть несколько типов. Это динамическое. 1/2/3 или более.

3. Способ заключается в использовании рекурсии. Рекурсивно перейдите к типу и повторите значение типа и добавьте в список.

Ответ №1:

Сначала преобразуйте typeBOsMap в List<Map.Entry<String, List<String>>>

   List<Map.Entry<String, List<String>>> list = typeBOsMap.entrySet().stream().collect(Collectors.toList());
  

Затем рекурсивно переставить все возможные комбинации

   List<List<Map.Entry<String, String>>> permute(List<Map.Entry<String, List<String>>> list,
      int index, List<Map.Entry<String, String>> now) {
    if (index >= list.size()) {
      return Arrays.asList(now);
    }
    Map.Entry<String, List<String>> entry = list.get(index);
    List<List<Map.Entry<String, String>>> res = new ArrayList<>();
    for (String value : entry.getValue()) {
      List<Map.Entry<String, String>> newList = new ArrayList<>(now);
      newList.add(new AbstractMap.SimpleEntry<>(entry.getKey(), value));
      res.addAll(permute(list, index   1, newList));
    }
    return res;
  }
  

Вы можете вызвать эту функцию с помощью list

 List<List<Map.Entry<String, String>>> data = permute(list, 0, Collections.emptyList());
  

Вывод:

 [State=california, Region=west, Store=Reliance]
[State=california, Region=west, Store=Dmart]
[State=california, Region=east, Store=Reliance]
[State=california, Region=east, Store=Dmart]
[State=newyork, Region=west, Store=Reliance]
[State=newyork, Region=west, Store=Dmart]
[State=newyork, Region=east, Store=Reliance]
[State=newyork, Region=east, Store=Dmart]
  

Онлайн-демонстрация здесь

Комментарии:

1. Вы пробовали это решение? Не стесняйтесь спрашивать, есть ли у вас какие-либо вопросы?

2. Это круто. Именно то, что я хотел. Позже в коде я только что сделал stream.map(-> construct object) . при построении объекта я также выполняю итерацию inner map для получения key,values . Я думаю, что имя функции следует переименовать в combine , что скажете?

3. Это полностью зависит от личного вкуса.