Yanıtlar:
Alan listesini tekrarlamaktan kaçınmasa da, burada daha ince bir şey var. Parametre ihtiyacını önlemek için "parametre yok etme" işlevini kullanır v
.
({id, title}) => ({id, title})
(Buradaki çalıştırılabilir bir örneğe bakın diğer cevaptaki ).
@ EthanBrown'un çözümü daha geneldir. İşte onun özelliklerini kullanan Object.assign
ve hesaplanan özellikleri ([p]
parça) :
function pick(o, ...props) {
return Object.assign({}, ...props.map(prop => ({[prop]: o[prop]})));
}
configurable
Sayılamayan ve ayarlayıcılar gibi özelliklerin özelliklerini korumak ve numaralandırılamayan özellikleri atlamak istiyorsak , o zaman:
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)})))
);
}
filter(...).map(prop => ({[prop]: get(prop)})))
?
pick()
uygulamanız için de böyle bir şey yapabilirsinizreturn props.reduce((r, prop) => (r[prop] = o[prop], r), {})
undefined
. Bazen önemlidir. Bunun dışında güzel bir fikir.
Cevabınızdan (veya torazburo'lardan) çok daha kompakt hale getirmenin bir yolu olduğunu düşünmüyorum, ancak aslında yapmaya çalıştığınız şey Underscore'un pick
çalışmasını taklit etmektir . Bunu ES6'da yeniden uygulamak yeterince kolay olurdu:
function pick(o, ...fields) {
return fields.reduce((a, x) => {
if(o.hasOwnProperty(x)) a[x] = o[x];
return a;
}, {});
}
Sonra kullanışlı bir yeniden kullanılabilir fonksiyonunuz var:
var stuff = { name: 'Thing', color: 'blue', age: 17 };
var picked = pick(stuff, 'name', 'age');
pick
işlevi bir kez doğru yapın ve istediğiniz kadar özellik seçebilirsiniz ve bunları iki katına çıkarmaz.
hasOwnProperty
? Alanlar elle seçilirse, in
daha uygun görünebilir; Ben kontrol tamamen atlamak ve sadece varsayılan izin için gitmek istiyorum rağmen undefined
.
Bunu tek katmanlı olarak çözmenin hilesi, alınan yaklaşımı tersine çevirmektir: Orijinal nesneden başlamak yerine orig
çıkarmak istedikleri anahtarlardan başlayabilir.
Array#reduce
Birini kullanmak daha sonra gerekli her anahtarı,initialValue
adı geçen işlev için .
Şöyle ki:
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"}
Virgül operatörünü kullanarak biraz daha kısa bir çözüm:
const pick = (O, ...K) => K.reduce((o, k) => (o[k]=O[k], o), {})
console.log(
pick({ name: 'John', age: 29, height: 198 }, 'name', 'age')
)
pick
bu konudaki diğer fonksiyonlar gibi çalışıyor :pick({ name: 'John', age: 29, height: 198 }, 'name', 'age')
TC39'un nesne dinlenme / yayılma özellikleri teklifi , bu oldukça kaygan olacaktır:
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
z; // { a: 3, b: 4 }
( Gereksinim duymayabileceğiniz x
ve y
değişkenleri yaratmanın dezavantajı vardır .)
omit
, ama değilpick
let { a, b } as z = { x: 1, y: 2, a: 3, b: 4 }
Var olan nesneden özellikleri açmak ve bunları farklı adlara sahip değişkenlere atamak için yeni ve başlangıçta boş bir nesnenin alanlarını kullanabilirsiniz.
const person = {
fname: 'tom',
lname: 'jerry',
aage: 100,
}
let newPerson = {};
({fname: newPerson.fname, lname: newPerson.lname} = person);
console.log(newPerson);
ES6, sorunun yazıldığı zamanki en son spesifikasyondu. Bu cevapta açıklandığı gibi , anahtar toplama ES2019'da ES6'dan önemli ölçüde daha kısadır:
Object.fromEntries(
Object.entries(obj)
.filter(([key]) => ['foo', 'bar'].includes(key))
)
Şu anda JavaScript'in nesne kısayol sözdizimini geliştirmek için, adlandırılmış özelliklerin tekrarlanmadan "seçilmesini" sağlayacak bir strawman teklifi var:
const source = {id: "68646", genre: "crime", title: "Scarface"};
const target = {};
Object.assign(target, {source.title, source.id});
console.log(picked);
// {id: "68646", title: "Scarface"}
Ne yazık ki, teklif yakında herhangi bir yere gitmiyor gibi görünüyor. En son Temmuz 2017'de düzenlendi ve hala Aşama 0'da , yazarın hendekte veya unutmuş olabileceğini gösteren bir taslak .
Düşündüğüm kısaca, kimsenin artık kullanmadığı eski bir dil özelliği içeriyor :
Object.assign(target, {...(o => {
with(o) return { id, title };
})(source)});
with
ifadeler katı modda yasaktır, bu da modern JavaScript'in% 99,999'u için bu yaklaşımı işe yaramaz hale getirir. Biraz utanç verici, çünkü bu with
özellik için bulduğum tek yarım kullanımlık kullanım . 😀
Ethan Brown'ın çözümüne benziyorum, ama daha kısa - pick
işlev. Başka bir işlev pick2
biraz daha uzun (ve daha yavaş), ancak özellikleri ES6'ya benzer şekilde yeniden adlandırmaya izin veriyor.
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
}, {})
Kullanım örneği:
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" }
Bu çözümü istemiştim, ancak önerilen anahtarların mevcut olup olmadığını bilmiyordum. Bu yüzden @torazaburo yanıtını aldım ve kullanım durumum için geliştirdim:
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' }
https://stackoverflow.com/users/865693/shesek'in azaltma yaklaşımından esinlenerek :
const pick = (orig, ...keys) => keys.reduce((acc, key) => ({...acc, [key]: orig[key]}), {})
kullanımı:
pick({ model : 'F40', manufacturer: 'Ferrari', productionYear: 1987 }, 'model', 'productionYear')
sonuç:
{model: "F40", productionYear: 1987}
Object.assign
; es6, altında pek çok hediye bulunan bir Noel ağacı gibidir, tatilden aylar sonra hala hediyeler buluyorum