Реструктуризация Javascript объекта путем группировки и декартового произведения - PullRequest
0 голосов
/ 24 января 2019

У меня есть некоторый сырой javascript, возвращенный из API, который выглядит следующим образом:

     {"Values":
    [
 {
        "fieldValue": 1,
        "fieldName": "A"
      },
      {
        "fieldValue": 2,
        "fieldName": "A"
      },
      {
        "fieldValue": "FOO",
        "fieldName": "B"
      },
      {
        "fieldValue": "BAR",
        "fieldName": "B"
      }
    ]
}

Я хочу реструктурировать его таким образом, который требует группировки атрибутов, преобразования атрибутов в значения и декартового объединения, в результате которого получается массив объектов, который выглядит следующим образом:

[{"A":1,"B":"FOO"},{"A":2,B:"FOO"},{"A":1,"B":"BAR"},{"A":2,"B":"BAR"}]

Я смотрю на библиотеку loDash и loDash.product, которая полезна, но не совсем подходит мне. _Groupby дает мне объект массивов, а не массив объектов:

{object:
[fieldName:"A",fieldValue:1],[fieldName:"A",fieldValue:2],[fieldName:"B",fieldValue:1],[fieldName:"B",fieldValue:2]
}

1 Ответ

0 голосов
/ 24 января 2019

Сначала создайте объект с использованием заданных данных и соберите ключи и их значения.

{
    A: [1, 2],
    C: ["FOO", "BAR"]
}

Тогда получите декартово произведение этого объекта.

Функция getCartesian разделяет все пары ключ / значение и создает новый декартовой продукт, перебирая значения, если массив с объектами снова вызывает getCartesian, и создает новые объекты.

Это работает и для вложенных объектов.

Алгоритм довольно прост, потому что он принимает любое свойство со значением, а не только массив или объект, и сохраняет это значение и перебирает все другие свойства, которые являются массивами или объектами. Этот алгоритм сохраняет внутреннюю структуру и принимает в качестве значения результата только примитивные значения для данной структуры.

Вначале он берет объект / массив, получает все записи и повторяет их, используя массив с пустым объектом.

Пустой массив temp - это новый результат.

Для создания новых элементов аккумулятор r повторяется и собираются новые значения. Это та часть, где создается первый уровень декартового произведения.

Для более глубокого уровня проверяется значение, а также "если объект", затем выполняется рекурсивный вызов, и для фактического ключа принимается новый результат.

function getCartesian(object) {
    return Object.entries(object).reduce((r, [k, v]) => {
        var temp = [];
        r.forEach(s =>
            (Array.isArray(v) ? v : [v]).forEach(w =>
                (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                    temp.push(Object.assign({}, s, { [k]: x }))
                )
            )
        );
        return temp;
    }, [{}]);
}

var data = { Values: [{ fieldValue: 1, fieldName: "A" }, { fieldValue: 2, fieldName: "A" }, { fieldValue: "FOO", fieldName: "C" }, { fieldValue: "BAR", fieldName: "C" }] },
    temp = data.Values.reduce((r, { fieldName, fieldValue }) => {
        (r[fieldName] = r[fieldName] || []).push(fieldValue);
        return r;
    }, {}),
    cartesian = getCartesian(temp);

console.log(cartesian);
.as-console-wrapper { max-height: 100% !important; top: 0; }
...