Присвоение определенных объектов константе - JS [duplicate]

Я считаю, что наиболее полезно использовать Runnable для всех упомянутых причин, но иногда мне нравится продлить Thread, поэтому я могу создать свой собственный метод остановки потока и вызвать его непосредственно на созданном мной потоке.

119
задан Michał Perłakowski 25 August 2016 в 16:58
поделиться

7 ответов

Вот что-то более тонкое, хотя оно не позволяет повторить список полей. Он использует «деструктурирование параметров», чтобы избежать необходимости в параметре v.

({id, title}) => ({id, title})

@ Решение EthanBrown является более общим. Вот более идиоматическая версия, которая использует Object.assign и вычисленные свойства (часть [p]):

function pick(o, ...props) {
    return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}

Если мы хотим сохранить атрибуты свойств, такие как configurable и геттеры и сеттеры, а также опуская неперечислимые свойства, тогда:

function pick(o, ...props) {
    var has = p => o.propertyIsEnumerable(p),
        get = p => Object.getOwnPropertyDescriptor(o, p);

    return Object.defineProperties({},
        Object.assign({}, ...props
            .filter(prop => has(prop))
            .map(prop => ({prop: get(props)})))
    );
}
89
ответ дан user 18 August 2018 в 07:45
поделиться
  • 1
    +1 приятный ответ, торазабуро; спасибо за то, что я понял Object.assign; es6 похож на рождественскую елку с таким количеством подарков под ней. Я все еще нахожу подарки через несколько месяцев после отпуска – Ethan Brown 27 May 2015 в 20:57
  • 2
    Получена ошибка: Описание свойства должно быть объектом: undefined. Разве это не должно быть filter(...).map(prop => ({[prop]: get(prop)})))? – Endless 22 November 2017 в 04:20
  • 3
    Для вашей первой реализации pick() вы также можете сделать что-то вроде return props.reduce((r, prop) => (r[prop] = o[prop], r), {}) – Patrick Roberts 31 January 2018 в 20:47
  • 4
    к сожалению, эта версия выбора не будет безопасна по типу в потоке или машинописном тексте. если вы хотите, чтобы тип безопасности, нет пути вокруг назначения структуры оригинального объекта, а затем присваивания каждого в новый объект. – duhseekoh 8 March 2018 в 00:08

Я имею сходство с решением Итана Брауна, но еще короче - pick. Другая функция pick2 немного длиннее (и медленнее), но позволяет переименовывать свойства в соответствии с образом ES6.

const pick = (o, ...props) => props.reduce((r, p) => p in o ? {...r, [p]: o[p]} : r, {})

const pick2 = (o, ...props) => props.reduce((r, expr) => {
  const [p, np] = expr.split(":").map( e => e.trim() )
  return p in o ? {...r, [np || p]: o[p]} : r
}, {}) 

Вот пример использования:

const d = { a: "1", c: "2" }

console.log(pick(d, "a", "b", "c"))        // -> { a: "1", c: "2" }
console.log(pick2(d, "a: x", "b: y", "c")) // -> { x: "1", c: "2" }
1
ответ дан Alexandr Priezzhev 18 August 2018 в 07:45
поделиться
  • 1
    В чем причина понижения? Разве это не работает для вас? – Alexandr Priezzhev 15 June 2017 в 15:35

Мне потребовалось это разрешение, но я не знал, доступны ли предлагаемые ключи. Итак, я принял @torazaburo ответ и улучшил для моего варианта использования:

function pick(o, ...props) {
  return Object.assign({}, ...props.map(prop => {
    if (o[prop]) return {[prop]: o[prop]};
  }));
}

// Example:
var person = { name: 'John', age: 29 };
var myObj = pick(person, 'name', 'sex'); // { name: 'John' }
0
ответ дан Alwin Kesler 18 August 2018 в 07:45
поделиться

Предложение свойств остаточного / расширенного объекта объекта TC39 сделает это довольно гладким:

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
z; // { a: 3, b: 4 }

(У него есть недостаток в создании переменных x и y которые вам могут не понадобиться.)

6
ответ дан alxndr 18 August 2018 в 07:45
поделиться

Трюк для решения этого вопроса как однострочного заключается в переводе принятого подхода: вместо того, чтобы начинать с исходного объекта orig, можно начинать с ключей, которые они хотят извлечь.

Используя Array#reduce можно сохранить каждый необходимый ключ на пустом объекте, который передается как initialValue для указанной функции.

Так же:

const orig = {
  id: 123456789,
  name: 'test',
  description: '…',
  url: 'https://…',
};

const filtered = ['id', 'name'].reduce((result, key) => { result[key] = orig[key]; return result; }, {});

console.log(filtered); // Object {id: 123456789, name: "test"}

13
ответ дан Bramus 18 August 2018 в 07:45
поделиться

Я не думаю, что есть способ сделать его намного более компактным, чем ваш ответ (или torazburo's), но в основном то, что вы пытаетесь сделать, это эмулировать операцию Underscore pick . Было бы достаточно легко повторить реализацию в ES6:

function pick(o, ...fields) {
    return fields.reduce((a, x) => {
        if(o.hasOwnProperty(x)) a[x] = o[x];
        return a;
    }, {});
}

. Тогда у вас есть удобная функция повторного использования:

var stuff = { name: 'Thing', color: 'blue', age: 17 };
var picked = pick(stuff, 'name', 'age');
36
ответ дан Ethan Brown 18 August 2018 в 07:45
поделиться
  • 1
    Благодарю. Это не ответ на мой вопрос, но очень приятное дополнение. – kirilloid 18 September 2014 в 12:48
  • 2
    (пожал плечами) Я чувствую, что есть ответ для вашего решения; нет более тонкого решения general (решение torazaburo удаляется из дополнительного глагола, но основная проблема - все имена свойств должны быть записаны дважды - означает, что он не масштабируется лучше вашего решения) , Мое решение, по крайней мере, хорошо масштабируется ... справа от функции pick один раз, и вы можете выбрать столько свойств, которые хотите, и они не будут удваивать их. – Ethan Brown 18 September 2014 в 16:58
  • 3
    Почему вы используете hasOwnProperty? Если поля выбраны вручную, даже in представляется более подходящим; хотя я бы полностью отказался от проверки и просто дал им по умолчанию undefined. – Bergi 24 November 2015 в 01:19
  • 4
    Берги, это разумный момент ... Я просто рассматриваю свойства (а не методы) в цепочке прототипов, чтобы быть странным и «вонючим». (так как они представляют собой запах кода), и я предпочитаю их фильтровать по умолчанию. Если есть приложение, которое нуждается в свойствах прототипа, хорошо ... для этого может быть вариант. – Ethan Brown 24 November 2015 в 04:34
  • 5
    как насчет массивов json! – Rizwan Patel 14 September 2017 в 12:48

Маленькое более короткое решение с использованием оператора запятой:

const pick = (O, ...K) => K.reduce((o, k) => (o[k]=O[k], o), {})
5
ответ дан shesek 18 August 2018 в 07:45
поделиться
  • 1
    как это использовать? Можете ли вы привести пример? – Tomas M 9 January 2018 в 10:52
  • 2
    Он работает так же, как другие функции pick в этом потоке: pick({ name: 'John', age: 29, height: 198 }, 'name', 'age') – shesek 11 January 2018 в 16:38
Другие вопросы по тегам:

Похожие вопросы: