как ограничить количество функций каждого? - PullRequest
0 голосов
/ 29 апреля 2019

У меня есть следующий объект:

"data": [
  {
   "label": "dataName",
   "sections": [
     {
      "label": "label sections 1",
      "fields": [
         {
          "id": 1,
          "name": "field 1",
          "value": "value field 1"
         },
         {
          "id": 2,
          "name": "field 2",
          "value": "value field 2"
         }
        ]
      },
    {
      "label": "label sections 2",
      "fields": [
        {
         "id": 5,
         "name": "field 3",
         "value": "value field 3"
        }
       ]
     }
   ]

Я хотел бы создать новый массив, извлекая данные из каждого поля.

как это:

  array [
      {id: field.id, name: field.name, value: field.value }
      {id: field.id, name: field.name, value: field.value }
  ]

Я думал, что буду использовать каждую функцию следующим образом:

    _.each(data, function (elt) {
            _.each(elt.ections, function (elt) {
            ....
         })
     });

но используя каждую функцию, я должен умножить каждую функцию.

Есть ли решение получить тот же результат без использования нескольких функций каждая?

Если у вас есть решение?

1018 * Сердечно *

Ответы [ 4 ]

2 голосов
/ 29 апреля 2019

Используйте метод уменьшения:

var reduceSections = data.reduce((a,b) => (a.concat(b.sections)),[]);
var reduceFields = reduceSections.reduce((a,b) => (a.concat(b.fields)),[]);
var result = reduceFields;
console.log(result);

Для получения дополнительной информации см.

ДЕМО

var data = [{
   "label": "dataName",
   "sections": [{
      "label": "label sections 1",
      "fields": [{
          "id": 1,
          "name": "field 1",
          "value": "value field 1"
      },{
          "id": 2,
          "name": "field 2",
          "value": "value field 2"
      }]
   },{
      "label": "label sections 2",
      "fields": [{
         "id": 5,
         "name": "field 3",
         "value": "value field 3"
      }]
   }]
}];
var reduceSections = data.reduce((a,b) => (a.concat(b.sections)),[]);
var reduceFields = reduceSections.reduce((a,b) => (a.concat(b.fields)),[]);
var result = reduceFields;
console.log(result);

Единственным недостатком является то, что изменение исходного объекта данных приведет к изменению результата в массиве. (без мелкого клонирования)

Это может быть, а может и не быть недостатком в зависимости от приложения.

Если вы хотите клонировать объекты:

var clone = result.map(obj => Object.assign({},obj));

Для получения дополнительной информации см.

1 голос
/ 29 апреля 2019

Поскольку вы уже используете lodash, у вас есть доступ к _.flatMap, _.map и _.clone.

К сожалению, с вашей структурой данных требуется перебор массивов в ваших данных, но в зависимости от того, чего вы пытаетесь достичь, существуют альтернативы _.each.

Если вы хотите объединить все клонированные записи в fields, которые вложены в каждую запись массива sections, которые вложены в каждую запись массива data, вы можете использовать следующий код:

function cloneFields(elt) { return _.map(elt.fields, _.clone) }

var allClonedFields = _.flatMap(data, elt => {
  return _.flatMap(elt.sections, cloneFields);
});

Функция cloneFields() инициализируется вне цикла для повышения производительности, поэтому она не 't создается на каждой итерации.

Этот код извлекает каждую запись в данных, затем из этой записи извлекает каждую запись в ключе section, затем возвращает клон каждой записи в ключе fields и затем присоединяется к ним.в один большой массив, дающий следующий результат:

[ { id: 1, name: 'field 1', value: 'value field 1' },
  { id: 2, name: 'field 2', value: 'value field 2' },
  { id: 5, name: 'field 3', value: 'value field 3' } ]
0 голосов
/ 29 апреля 2019

Если вы точно не знаете, насколько "глубок" ваш объект, я рекомендую вам использовать рекурсивную функцию.Вот что я предлагаю:

function recursivlyCreateObject(data) {
    let result;
    if(Array.isArray(data)) {
        result = [];
        data.forEach(function(element) {
            result.push(recursivlyCreateObject(element));
        });
    } else {
        result = {};
        Object.keys(data).forEach(function(key) {
            result[key] = data[key];
        });
    }
    return result;
}

Вы можете проверить это здесь

РЕДАКТИРОВАТЬ : обратите внимание, что это не будет делать гораздо больше, чемпростой файл console.log над данными, но он может помочь вам в рекурсивной итерации объекта

0 голосов
/ 29 апреля 2019

Если я правильно понимаю, вы пытаетесь получить свойство fields у каждого элемента в массиве.Чтобы сделать это, взгляните на array.map () .

, используя array.map , вы можете сделать что-то вроде этого:

let array = data.map(x => x.fields);

или:

let array = data.map(x => (
    {id: x.fields.id,name: x.fields.name, value: x.fields.value }
));

https://www.w3schools.com/jsref/jsref_map.asp

...