Как условно создать свойство объекта в одной строке?

#javascript #node.js #typescript

Вопрос:

Я хочу создать свойство для объекта условно. Идея состоит в том, чтобы убедиться, что свойство не существует (так что не просто равно нулю), если оно не имеет значения.

Что я сейчас делаю:

 // comes from users
req.query = {
  foo: true
}

// my object which will contains allowed properties IF EXISTS
const where = {}

if (req.query.foo) {
  where.foo = req.query.foo
}
if (req.query.bar) {
  where.bar = req.query.bar
}

console.log(where) 

Действительно скучно повторять это для каждого отдельного свойства…

Есть ли способ сделать это в одной строке?

Редактировать:

Я не хочу получать все свойства от req.query

Ответ №1:

Создайте свойство объекта obj.foo, если существует значение (или любое другое условие)

amp;amp; оператор возвращает второй элемент, если выполнено первое логическое условие

оператор распространения es6 ... делает то, что он делает)

 const value = 'bar'

const empty = undefined

const obj = {
  ...value amp;amp; { foo: value }, // read ...(value amp;amp; { foo: value }) parenthesis are not necessary
  ...empty amp;amp; { empty },
  ...(100 > 0) amp;amp; { condition: 'true' },
  ...(100 < 0) amp;amp; { condition: 'false' },
}

console.log(obj) 

Комментарии:

1. Извините… можете ли вы это объяснить ?

2. Свойство Создать объект условно const value существует, поэтому obj.foo создается, const empty undefined поэтому свойство obj.empty не создается

3. Спасибо, мне не было ясно, что оператор распространения влияет на правую сторону оператора amp;amp;

4. @mbesson Да, извините, есть даже правило eslint, которое добавляет скобки, чтобы было понятнее)

Ответ №2:

Вы могли бы сделать:

 const merged = {...where, ...req.query};
 

Комментарии:

1. Thx, но req. запрос содержит дополнительные свойства, и я не хочу, чтобы они были объединены

2. Итак, тогда вы, вероятно, захотите использовать ответ мустафы

Ответ №3:

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

 const elements = ["foo", "bar"];

elements.forEach(el => {
    if (req.query[el]) {
        where[el] = req.query[el];
    }
});
 

Комментарии:

1. Это заставляет нас создавать массив ключей и обновлять его, что выглядит не очень хорошо

2. @NikitaMazur Вам нужно знать, какие ключи вас интересуют, и это будет где-то, почему бы не в списке в одном месте?

3. @BenStephens ты прав, тебе все равно нужно следить за ключами.

Ответ №4:

Вы можете просто написать это в одной строке, вот так :

 let where = {};
if (req.query.foo) where = {...where, foo : req.query.foo };
if (req.query.bar) where = {...where, bar : req.query.bar }; 

Я надеюсь, что это поможет.

Ответ №5:

Если вам нужен простой однострочный текст (возможно, менее читаемый), вы можете сделать:

 Object.keys(req.query).forEach(key => req.query[key] amp;amp; (where[key] = req.query[key]));
 

Комментарии:

1. если req. запрос.ключ = не определен, он создаст where.ключ = не определен

2. добавил чек на это

Ответ №6:

Если вы не против добавить функцию выщипывания, вы могли бы сделать это так:

 const req = { query: { baz: '1', foo: '3' } };
const where = {};

const pluck = (keys, obj) =>
  keys.reduce((a, k) => typeof obj[k] === 'undefined' ? a : Object.assign(a, { [k]: obj[k] }), {});

const add_foo_bar = (where, query) =>
  Object.assign({}, where, pluck(['foo', 'bar'], query));

const res = add_foo_bar(where, req.query);

console.log(res); 

Комментарии:

1. Я думаю, что это более чистое решение, но я искал решение без добавления функции