Использование lodash для отображения сложных JSON

susanoo спросил: 28 марта 2018 в 04:38 в: javascript

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

ПЕРВЫЙ ОДИН

from:

  types: {
      one: [0.0954835843,6.054385,84.40238],
      two: [0.0954835843,6.054385,84.40238],
      three: [0.0954835843,6.054385,84.40238]
    },

to

    types: [
      [0.0954835843,6.054385,84.40238 , 'one'],
      [0.0954835843,6.054385,84.40238, 'two'],
      [0.0954835843,6.054385,84.40238, 'three']
    ],

SECOND ONE соответствует идентификатору, получая данные из двух объектов

          types:[{
            id:1, 
            data:[
                    [
                        'temp',
                        '46%',
                        '14.00',
                        '1388.68561604',
                        '1388.68561604',
                        '2018-02-12 18:21'                    ],
                    [
                        'nottemp',
                        '46%',
                        '14.00',
                        '1388.68561604',
                        '1388.68561604',
                        '2018-02-12 18:21'                    ],
               ] 
            },
            {
            id:2, 
            data:[
                    [
                        'temp',
                        '46%',
                        '14.00',
                        '1388.68561604',
                        '1388.68561604',
                        '2018-02-12 18:21'                    ],
                    [
                        'nottemp',
                        '46%',
                        '14.00',
                        '1388.68561604',
                        '1388.68561604',
                        '2018-02-12 18:21'                    ],
               ] 
            }]data: [
        {
          id: 1,
          name: 'sibling',
        },
        {
          id: 2,
          name: 'parent',
        },
     ]

и в итоге все элементы из типов .data в формате, например:

        [
                'temp',
                '46%',
                '14.00',
                '1388.68561604',
                '1388.68561604',
                '2018-02-12 18:21'
                'parent' //or sibling, depends on id            ]

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

ИЗМЕНИТЬ для второй проблемы, которую у меня есть:

   mapElement: function(){
        let that=this;
        return _.map(this.getTypesData,function(element){
          let data=[];
          let pairName = that.getFamily(element.id); //todo: matching id of Type with id of object with names
          element.data.forEach(function(element){
            data.push([
              pairName,
              element[0],
              element[1],
              element[2],
            ]);
          });
          return data;
        });
      }

4 ответа

Есть решение
Kai ответил: 28 марта 2018 в 05:38

супер просто с _.map:

// Also handle case value is not array
types = _.map(types, (val, key) => _.isArray(val) ? v.concat(key) : [val].concat(key)); 

я оптимизировал производительность:

//clone to new object to avoid modifying original data
const cloneData = _.cloneDeep(data);types = _.map(types, (val, key) => {
    const index = _.findIndex(cloneData, { id: val.id});
    val.data = _.map(val.data, (v)=> _.isArray(v) ?v.concat(cloneData[index].name) : [v].concat(cloneData[index].name));
    //remove when found id to shorten the array
    // if the types[].id is not unique, remove this
    cloneData.splice(index,1);    return val;
})
CertainPerformance ответил: 28 марта 2018 в 05:03

Для первого просто используйте Object.entries и добавьте ключ в конец:

const obj = {
  types: {
    one: [0.0954835843, 6.054385, 84.40238],
    two: [0.0954835843, 6.054385, 84.40238],
    three: [0.0954835843, 6.054385, 84.40238]
  },
};
obj.types = Object.entries(obj.types)
  .map(([key, val]) => [...val, key]);
console.log(obj);

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

const types = [{
    id: 1,
    data: [
      [
        'temp',
        '46%',
        '14.00',
        '1388.68561604',
        '1388.68561604',
        '2018-02-12 18:21'

      ],
      [
        'nottemp',
        '46%',
        '14.00',
        '1388.68561604',
        '1388.68561604',
        '2018-02-12 18:21'

      ],
    ]
  },
  {
    id: 2,
    data: [
      [
        'temp',
        '46%',
        '14.00',
        '1388.68561604',
        '1388.68561604',
        '2018-02-12 18:21'

      ],
      [
        'nottemp',
        '46%',
        '14.00',
        '1388.68561604',
        '1388.68561604',
        '2018-02-12 18:21'

      ],
    ]
  }
];

const data = [
  {
    id: 1,
    name: 'sibling',
  },
  {
    id: 2,
    name: 'parent',
  },
];

types.data = types.map(({ id, data: typesData }) => {
  const str = data.find(({ id: dataId }) => dataId === id).name;
  return typesData.map(arr => [...arr, str]);
});
console.log(types.data);
Amthieu ответил: 28 марта 2018 в 05:12

Первый:

const newTypes1 = Object.keys(obj.types).map(t => {
  return [...obj.types[t], t];
});

Второй:

types.forEach(t => {
  const name = data.find(function(x) { return x.id == t.id }).name;
  t.data.forEach(d => { d.push(name) });
});

РЕДАКТИРОВАТЬ: для первого: Создается новый массив, а для второго имя помещается в массив, поэтому вы сохраняете тот же объект.

Satish Kumar ответил: 28 марта 2018 в 05:18

Попробуйте это,

const input = {types: {
      one: [0.0954835843,6.054385,84.40238],
      two: [0.0954835843,6.054385,84.40238],
      three: [0.0954835843,6.054385,84.40238]
    },
}
const output = Object.keys(input.types).map((key,val) => {
  return [...input.types[key],key];
})
console.log(output);

1. Используйте Object.keys для получения ключей объекта (lodash, _ .keys ()).

2.

return [...input.types[key],key]

Приведенную выше строку можно разбить (для лучшего понимания) на

const returnVal = _.clone(input.type[key]).push(key);
return returnVal

Если у вас есть идея, вы можете попробовать 2-й самостоятельно.

CertainPerformance ответил: 28 марта 2018 в 05:08
Вы не должны использовать let, если не собираетесь переназначать переменную - используйте вместо этого const.
Satish Kumar ответил: 28 марта 2018 в 05:10
@CertainPerformance. Я буду иметь в виду, в следующий раз.