Tutaj jest coś szczuplejszego, chociaż nie unika to powtarzania listy pól. Używa „destrukturyzacji parametrów”, aby uniknąć konieczności stosowania v
parametru.
({id, title}) => ({id, title})
(Zobacz działający przykład w tej innej odpowiedzi ).
Rozwiązanie @ EthanBrown jest bardziej ogólne. Oto bardziej idiomatyczna wersja tego, która wykorzystuje Object.assign
i obliczone właściwości ( [p]
część):
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
i pobierające i ustawiające, jednocześnie pomijając niewliczalne 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)})))
);
}
Object.assign
; es6 jest jak choinka z tak wieloma prezentami pod nią, że wciąż znajduję prezenty miesiące po wakacjachfilter(...).map(prop => ({[prop]: get(prop)})))
?pick()
wdrożenia możesz również zrobić coś takiegoreturn props.reduce((r, prop) => (r[prop] = o[prop], r), {})
undefined
. Czasami to ma znaczenie. Poza tym niezły pomysł.Nie sądzę, że istnieje jakiś sposób, aby uczynić go znacznie bardziej zwarty niż odpowiedź (lub torazburo'S), ale przede wszystkim to, co próbujesz zrobić, to Emulate podkreślenia jest
pick
operacja . Byłoby łatwo ponownie zaimplementować to w ES6:W takim razie masz przydatną funkcję wielokrotnego użytku:
źródło
pick
raz popraw funkcję, a możesz wybrać dowolną liczbę właściwości, a to ich nie podwoi.hasOwnProperty
? Jeśli pola są wybierane ręcznie, nawetin
wydaje się bardziej odpowiednie; chociaż chciałbym całkowicie pominąć sprawdzanie i po prostu pozwolić im domyślnieundefined
.Sztuczka pozwalająca rozwiązać ten problem jako jednolinijkowy polega na odwróceniu przyjętego podejścia: zamiast zaczynać od oryginalnego obiektu
orig
, można zacząć od kluczy, które chcą wyodrębnić.Używając
Array#reduce
go, można następnie przechowywać każdy potrzebny klucz w pustym obiekcie, który jest przekazywany jako funkcjainitialValue
dla tej funkcji.Tak jak to:
źródło
Trochę krótsze rozwiązanie wykorzystujące operator przecinka:
źródło
pick
funkcje w tym wątku:pick({ name: 'John', age: 29, height: 198 }, 'name', 'age')
Propozycja właściwości spoczynku / rozłożenia obiektu TC39 sprawi, że będzie to całkiem sprytne:
(Ma tę wadę, że tworzy zmienne
x
iy
, których możesz nie potrzebować).źródło
omit
, ale niepick
let { a, b } as z = { x: 1, y: 2, a: 3, b: 4 }
Możesz użyć destrukturyzacji obiektów do wypakowania właściwości z istniejącego obiektu i przypisania ich do zmiennych o różnych nazwach - pól nowego, początkowo pustego obiektu.
źródło
ES6 była najnowszą specyfikacją w momencie pisania pytania. Jak wyjaśniono w tej odpowiedzi , wybieranie kluczy jest znacznie krótsze w ES2019 niż w ES6:
źródło
Obecnie istnieje propozycja strawmana dotycząca ulepszenia skróconej składni obiektów JavaScript, która umożliwiłaby „wybieranie” nazwanych właściwości bez ich powtarzania:
Niestety, ta propozycja nie wydaje się wkrótce nigdzie trafiać. Ostatnio edytowany w lipcu 2017 r. I nadal jest szkicem na etapie 0 , co sugeruje, że autor mógł porzucić go lub o nim zapomnieć.
ES5 i starsze (tryb nieścisły)
Najbardziej zwięzły możliwy skrót, jaki przychodzi mi do głowy, dotyczy cechy starożytnego języka, której nikt już nie używa:
with
instrukcje są zabronione w trybie ścisłym, przez co takie podejście jest bezużyteczne dla 99,999% współczesnego JavaScript. Szkoda, bo to jedyne w połowie przyzwoite zastosowanie tejwith
funkcji, jakie znalazłem . 😀źródło
Mam rozwiązanie podobne do rozwiązania Ethana Browna, ale jeszcze krótsze -
pick
funkcję. Inna funkcjapick2
jest nieco dłuższa (i wolniejsza), ale pozwala zmieniać nazwy właściwości w podobny sposób jak w ES6.Oto przykład użycia:
źródło
Potrzebowałem tego rozwiązania, ale nie wiedziałem, czy proponowane klucze są dostępne. Więc wziąłem odpowiedź @torazaburo i poprawiłem dla mojego przypadku użycia:
źródło
zainspirowany podejściem redukującym https://stackoverflow.com/users/865693/shesek :
stosowanie:
pick({ model : 'F40', manufacturer: 'Ferrari', productionYear: 1987 }, 'model', 'productionYear')
prowadzi do:{model: "F40", productionYear: 1987}
źródło