Jednowierszowy do pobierania niektórych właściwości z obiektu w ES 6

Jak można napisać funkcję, która przyjmuje tylko kilka atrybutów w najbardziej zwarty sposób w ES6?

Wymyśliłem rozwiązanie używając destrukcji + uproszczonego dosłownego obiektu, ale nie podoba mi się, że lista pól jest powtarzana w kodzie.

Czy jest jeszcze szczuplejsze rozwiązanie?
(v) => {
    let { id, title } = v;
    return { id, title };
}
Author: Michał Perłakowski, 2014-08-28

7 answers

Tutaj jest coś szczuplejszego, chociaż nie unika powtarzania listy pól. Używa "destrukcji parametrów", aby uniknąć konieczności stosowania parametru v.

({id, title}) => ({id, title})
@ EthanBrown rozwiązanie jest bardziej ogólne. Poniżej znajduje się jego bardziej idiomatyczna wersja, która używa Object.assign i właściwości obliczeniowych (część [p]):
function pick(o, ...props) {
    return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}

Jeśli chcemy zachować atrybuty właściwości, takie jak configurable oraz gettery i settery, pomijając również nieoznaczalne właściwości, to:

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)})))
    );
}
 94
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-25 16:53:48

Myślę, że nie ma sposobu, aby uczynić go bardziej zwartym niż Twoja odpowiedź (lub torazburo), ale zasadniczo to, co próbujesz zrobić, to emulować operację pick . Łatwo byłoby ponownie zaimplementować to w ES6:

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

Następnie masz przydatną funkcję wielokrotnego użytku:

var stuff = { name: 'Thing', color: 'blue', age: 17 };
var picked = pick(stuff, 'name', 'age');
 36
Author: Ethan Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-15 15:59:59

Sztuką rozwiązania tego problemu jako jednowierszowego jest odwrócenie przyjętego podejścia: zamiast zaczynać od oryginalnego obiektu orig, można zacząć od kluczy, które chcą wydobyć.

Za pomocą Array#reduce Następnie można zapisać każdy potrzebny klucz na pustym obiekcie, który jest przekazywany jako initialValue dla wspomnianej funkcji.

Like so:

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"}
 16
Author: Bramus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 14:17:16

Nieco krótsze rozwiązanie za pomocą operatora przecinka:

const pick = (O, ...K) => K.reduce((o, k) => (o[k]=O[k], o), {})
 6
Author: shesek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 19:12:21

Tc39 ' s object rest/spread properties proposal properties sprawi, że będzie to całkiem sprytne:

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

(ma minusy tworzenia zmiennych x i y, których możesz nie potrzebować.)

 5
Author: alxndr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-03 18:29:01

Mam podobną do rozwiązania Ethana Browna, ale jeszcze krótszą - pick funkcję. Inna funkcja pick2 jest nieco dłuższa (i wolniejsza), ale umożliwia zmianę nazw właściwości w sposób podobny do 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
}, {}) 

Oto przykład użycia:

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
Author: Alexandr Priezzhev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-04 16:45:23

Wymagałem tego sollution, ale nie wiedziałem, czy proponowane klucze są dostępne. Więc wziąłem @torazaburo odpowiedź i poprawiłem dla mojego przypadku użycia:

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
Author: Alwin Kesler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-16 18:29:58