#javascript #ecmascript-6 #lodash
Вопрос:
Ниже приведены две функции, которые выполняют итерацию по коллекции объектов, чтобы оценить, равен ли идентификатор какого-либо объекта элементам аргументу идентификатора функции. Если true, то он устанавливает активный флаг и устанавливает текущую переменную равной идентификатору.
Примечания:
- функция longerVersion(идентификатор) , если подробный / более длинный подход
- функция shorterVersion(id) — мой текущий оптимальный подход
вопрос
- Существует ли лучший подход в ES6 и или lodash для достижения того же результата?
const items = {1:{id:1,active:false},2:{id:2,active:false}, 3:{id:3,active:false}}
let current = 0;
function longerVersion(id) {
for (const k in this.items) {
if (this.items[k].id === id) {
this.items[k].active = true
current = id
} else {
this.items[k].active = false
}
}
}
function shorterVersion(id) {
for (const k in this.items) {
items[k].active = items[k].id === id amp;amp; ((current = id) amp;amp; true)
}
}
longerVersion(2);
console.log(current); // expected outcome : (current === 2)
console.log(items); // expected outcome : items: {1:{id:1,active:false},2:{id:2,active:true}, 3:{id:3,active:false}}
shorterVersion(3);
console.log(current); // expected outcome : (current === 3)
console.log(items); // expected outcome : items: {1:{id:1,active:false},2:{id:2,active:false}, 3:{id:3,active:true}}
Комментарии:
1. Как вы относитесь к переключению элементов в массив? Тогда вы могли бы использовать массив. найдите и другие полезные функции вместо циклов for.
2. как «лучше»? «оптимальный» в каком смысле? Лично я ненавижу, когда задания смешиваются с логическими выражениями, но это, типа, мое мнение, чувак.
3. @HereticMonkey Я согласен, но тогда вы получите подробный вариант, который является тяжелым кодом
4. @Джеймс, я в порядке с массивом, кстати, если у вас есть решение
5. И именно поэтому у нас есть минификаторы, так что нам не нужно беспокоиться о подобном дерьме.
Ответ №1:
Обновление current
внутри области действия функции-это побочный эффект, которого вы хотите избежать. Вместо этого пусть это будет возвращаемое значение функции.
const items = {1:{id:1,active:false},2:{id:2,active:false}, 3:{id:3,active:false}};
const functionalVersion = (items, id) => Object.values(items).reduce((acc, x) => {
x.active = x.id === id;
return x.active ? id : acc;
}, -1);
let current = functionalVersion(items, 2);
console.log(current); // expected outcome : (current === 2)
console.log(items); // expected outcome : items: {1:{id:1,active:false},2:{id:2,active:true}, 3:{id:3,active:false}}
current = functionalVersion(items, 3);
console.log(current); // expected outcome : (current === 3)
console.log(items); // expected outcome : items: {1:{id:1,active:false},2:{id:2,active:false}, 3:{id:3,active:true}}
Функция возвращает a -1
, когда ни один из items
идентификаторов не совпадает с идентификатором.
Мне не нравятся задания в выражениях, но если это ваше дело, вы можете сделать это в одну строку:
const functionalVersion = (items, id) => Object.values(items).reduce((acc, x) => x.active = x.id === id ? id : acc, -1);
Комментарии:
1. Это прекрасно работает! Блестяще! Позволяет мне извлечь его в полезную функцию, которую я могу внедрить в любой компонент. Миллион раз спасибо!
Ответ №2:
Предполагая, что коллекция действительно является простым объектом и вам не нужны свойства, которые находятся в цепочке прототипов объекта, in
ключевое слово все чаще осуждается в пользу более новых Object.keys
и др. Вот подход, использующий это, функцию стрелки и необязательную цепочку, чтобы быть дополнительным Ecma-ish:
function ecmaVersion(id) {
const key = Object.keys(items).find((key) =>
items[key].active = (items[key].id === id))
return current = items[key]?.id
}
Эквивалент lodash будет включать _.findKey
в себя .
Комментарии:
1. «ключевое слово in все чаще осуждается в пользу более нового объекта.keys и др.» [требуется цитата].
2. Цитаты включают это объяснение ловушек 2012 года и правило ESLint для защиты
for...in
, чтобы избежать одной из них .Object.keys
и его родственники просто запекли это.