Ключ возврата Lodash, если существует, в противном случае вернуть другой ключ - PullRequest
1 голос
/ 21 октября 2019

Допустим, я хочу сделать что-то вроде:

const result = 'someKey' in myVar
  ? myVar.someKey
  : myVar.anotherKey

Я могу добиться того же, используя get(myVar, 'someKey', get(myVar, 'anotherKey')). Мне было интересно, есть ли другой метод lodash, который выглядит чище?

Ответы [ 2 ]

2 голосов
/ 21 октября 2019

Никакая встроенная функция в Lodash не позволяет этого (к сожалению). Однако, как сказал Александр Нид в своем ответе, вы можете легко создать для этого собственную функцию. Я буду использовать функциональность Lodash вместо обычного JavaScript, чтобы продемонстрировать, как он может работать:

function getFirst(item, paths) {
  const notFound = Symbol("not found");
  
  return _(paths)
    .map(path => _.get(item, path, notFound))
    .filter(result => result !== notFound)
    .first();
}

const obj = {
  a: {
    b: {
      c: 42
    }
  },
  x: {
    y: 1
  },
  z: 2
};

console.log(getFirst(obj, ['g']));
console.log(getFirst(obj, ['g', 'h', 'z']));
console.log(getFirst(obj, ['g', 'h', 'a.b.c', 'z']));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

Цепочка с использованием Lodash оценивается лениво, поэтому последовательность сопоставляет первый путь с _.get(item, path) и в случае неудачи возвращает уникальный notFound значение. Затем, если notFound отбрасывается, будет отображено следующее значение. Это продолжается до тех пор, пока не будет найдено совпадение или пока все члены paths не будут исчерпаны, а значение равно undefined.

1 голос
/ 21 октября 2019

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

function getFirst(obj, ...paths) {
    for (const path of paths) {
        if (_.has(obj, path)) {
            return _.get(obj, path);
        }
    }
    return;
}
...