Получить вложенное значение с помощью lodash - PullRequest
0 голосов
/ 24 июня 2019

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

Вот код, который я получил до сих пор:

const object = {
  screen: {
    '[data-id="123"]': {
      'font-family': 'Arial',
    },
    '[data-id="456"]': {
      'background-color': 'red',
      'font-family': 'Comic Sans',
    },
  },
};

const prop = 'font-family';
const props = [];

forEach(object, (selectors) => {
  forEach(selectors, (selector) => {
    if (prop in selector) {
      props.push(selector[prop]);
    }
  });
});

console.log(props);

В этом случае функция возвращает массив семейств шрифтов (обозначается prop const).

Я собираюсь использовать функции lodash, такие как map и reduce, ноЯ не знаю, с чего начать.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Поскольку это вложенный объект, он действительно будет зависеть от того, как вы хотите решить эту проблему. Если вы используете карту вложенным способом, вы получите вложенный массив. Чтобы соответствовать вашему выводу, вложенный массив может быть сведен.

_.flatten(_.map(object, (prop) => _.map(prop, (nestedProp) => nestedProp['font-family'])));

Но если вы не хотите использовать Reduce вместо Flatten, вы можете уменьшить вложенный массив из массива

_.reduce(_.map(object, (prop) => _.map(prop, (nestedProp) => nestedProp['font-family'])),(a, b) => [...a, ...b]);

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

0 голосов
/ 25 июня 2019

Вы можете использовать _.flatMap() для рекурсивной итерации объекта / массива и сбора всех значений с ключом, равным реквизиту:

const collect = (prop, obj) =>
  _.flatMap(obj, (v, k) => {
    if(k === prop) return v;
    
    return _.isObject(v) ? collect(prop, v) : [];
  });

const object = {
  screen: {
    '[data-id="123"]': {
      'font-family': 'Arial',
    },
    '[data-id="456"]': {
      'background-color': 'red',
      'font-family': 'Comic Sans',
    },
  },
};

const result = collect('font-family', object);

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

В ванильном JS вы можете использовать Object.entries() и Array.flatMap():

const collect = (prop, obj) =>
  Object.entries(obj).flatMap(([k, v]) => {
    if(k === prop) return v;
    
    return typeof v === 'object' && v !== null ? collect(prop, v) : [];
  });

const object = {
  screen: {
    '[data-id="123"]': {
      'font-family': 'Arial',
    },
    '[data-id="456"]': {
      'background-color': 'red',
      'font-family': 'Comic Sans',
    },
  },
};

const result = collect('font-family', object);

console.log(result);
...