Извлечение значения ключа из объекта в массив объектов с указанными c полями - PullRequest
0 голосов
/ 16 апреля 2020

Итак, у меня есть эти данные:

fields = ['a', 'b', 'c']
data = [{r: 1, a: 2, b: 3, c: 4, h: 5}, {r: 4, a: 9, b: 1, c: 4, h: 5} ... ]

, и я хочу иметь возможность (предпочтительно с loda sh), чтобы иметь возможность добраться до этого:

newData = [{r:1, h:5, values: [{name: 'a', value: 2},{name: 'b', value: 3}, {name: 'c', value: 4}], .....]

Значение только поля из объекта 'fields' извлекаются из каждого объекта в массиве (они всегда существуют) и помещаются в свойство 'values', у которого есть массив из них в формате, показанном здесь.

Хотелось бы услышать предложения о самом чистом способе достижения этого!

Я сделал это:

function something(data, fields) {

  const formattedData = _.map(data, (currData) => {

    const otherFields = _.omit(currData, fields)

    return { 
      ...otherFields, 
      values: _.flow( 
        currData => _.pick(currData, fields), 
        pickedFields => _.toPairs(pickedFields), 
        pairs => _.map(pairs, pair => { 
          return { name: pair[0], value: pair[1] } 
        })
      )(currData)
    }
  })

  return formattedData
}

, который работает, но мне интересно, не немного ли это сложно.

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

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

const
    fields = ['a', 'b', 'c'],
    data = [{ r: 1, a: 2, b: 3, c: 4, h: 5 }, { r: 4, a: 9, b: 1, c: 4, h: 5 }],
    result = data.map(o => {
        const values = fields.map(name => {
            let value;
            ({ [name]: value, ...o } = o);
            return { name, value };
        });
        return { ...o, values };
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 17 апреля 2020

Метод _.flow() создает функцию, которую вы можете извлечь и назвать. Кроме того, первая функция в потоке принимает более 1 параметра, поэтому вам не нужно передавать его явно. Поскольку _.toPairs() является унарным, вам не нужно заключать его в функцию со стрелкой. Создание объекта немного раздражает. Я использовал _.zipObject(), но это все еще громоздко.

Теперь вы можете использовать функцию create by _.flow() в своей основной функции, и она довольно читабельна:

const { flow, pick, toPairs, map, partial, zipObject, omit } = _

const propsToObjs = flow(
  pick,
  toPairs,
  pairs => map(pairs, partial(zipObject, ['name', 'value'])),
)

const fn = (data, fields) =>
  map(data, currData => ({
    ...omit(currData, fields), 
    values: propsToObjs(currData, fields)
  }))
  
const fields = ['a', 'b', 'c']
const data = [{r: 1, a: 2, b: 3, c: 4, h: 5}, {r: 4, a: 9, b: 1, c: 4, h: 5}]

const result = fn(data, fields)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Используя lodash / fp, мы можем сделать функцию потока еще более приятной, поскольку функции lodash / fp автоматически каррируются и повторяются в первую очередь data-last (not обратный порядок параметров):

const { flow, pick, toPairs, map, partial, zipObject, omit } = _

const propsToObjs = flow(
  pick,
  toPairs,
  map(zipObject(['name', 'value']))
)

const fn = fields => map(currData => ({
  ...omit(fields, currData), 
  values: propsToObjs(fields, currData)
}))
  
const fields = ['a', 'b', 'c']
const data = [{r: 1, a: 2, b: 3, c: 4, h: 5}, {r: 4, a: 9, b: 1, c: 4, h: 5}]

const result = fn(fields)(data)

console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
1 голос
/ 16 апреля 2020

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

fields = ["a", "b", "c"];
data = [
  { r: 1, a: 2, b: 3, c: 4, h: 5 },
  { r: 4, a: 9, b: 1, c: 4, h: 5 },
];

let newData = data.map((o) => {
  let newObject = {};
  newObject.values = [];
  for (let k in o) {
    if (fields.includes(k)) {
      newObject.values.push({
        name: k,
        value: o[k]
      });
    } else {
      newObject[k] = o[k];
    }
  }
  return newObject;
});

console.log(newData);
...