回答:
これはよりスリムなものですが、フィールドのリストを繰り返すことは避けられません。「パラメータのデストラチャリング」を使用して、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)})))
);
}
filter(...).map(prop => ({[prop]: get(prop)})))
?
pick()
実装では、次のようなこともできますreturn props.reduce((r, prop) => (r[prop] = o[prop], r), {})
undefined
ます。時にはそれが重要です。それ以外はいいアイデアです。
私はあなたの答え(またはtorazburoの答え)よりはるかにコンパクトにする方法はないと思いますが、基本的にあなたがしようとしているのは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');
pick
関数を1回正しく実行すれば、必要な数のプロパティを選択できますが、プロパティが2倍になることはありません。
hasOwnProperty
?フィールドが手動で選択されている場合は、in
さらに適切であるように見えます。ただし、チェックを完全に省略して、デフォルトのに設定しundefined
ます。
これをワンライナーとして解決する秘訣は、取られたアプローチを逆orig
にすることです。元のオブジェクトから開始する代わりに、抽出したいキーから開始することができます。
使用してArray#reduce
1は次にとして渡される空のオブジェクト上の各必要な鍵格納することができる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"}
TC39のオブジェクトレスト/スプレッドプロパティの提案により、これはかなり滑らかになります。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
z; // { a: 3, b: 4 }
(それはあなたが必要としないかもしれない変数x
とy
変数を作成することの欠点を持っています。)
omit
が、そうではありませんpick
let { a, b } as z = { x: 1, y: 2, a: 3, b: 4 }
オブジェクトの構造化を使用して、既存のオブジェクトからプロパティをアンパックし、それらを異なる名前の変数(新しい、最初は空のオブジェクトのフィールド)に割り当てることができます。
const person = {
fname: 'tom',
lname: 'jerry',
aage: 100,
}
let newPerson = {};
({fname: newPerson.fname, lname: newPerson.lname} = person);
console.log(newPerson);
現在、JavaScriptのオブジェクト短縮構文を改善するための提案があり、繰り返しなしで名前付きプロパティの「ピッキング」が可能になります。
const source = {id: "68646", genre: "crime", title: "Scarface"};
const target = {};
Object.assign(target, {source.title, source.id});
console.log(picked);
// {id: "68646", title: "Scarface"}
残念ながら、この提案はすぐにはどこにも行きません。最終編集者は2017年7月、まだドラフトはステージ0であり、作者がそれを破棄したか忘れたかを示唆しています。
私が考えることができる最も簡潔な可能な省略表現は、だれももう使用しない古代言語の機能に関係しています。
Object.assign(target, {...(o => {
with(o) return { id, title };
})(source)});
with
ステートメントは厳格モードでは禁止されているため、このアプローチは最新のJavaScriptの99.999%では役に立たなくなります。これは私がこのwith
機能で見つけた唯一の適切な使用法であるため、少し残念です。😀
私はイーサン・ブラウンの解決策に似ていますが、もっと短いです- 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" }
私はこの解決策を必要としましたが、提案されたキーが利用可能かどうかは知りませんでした。それで、私は@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' }
https://stackoverflow.com/users/865693/shesekのreduceアプローチに触発されました:
const pick = (orig, ...keys) => keys.reduce((acc, key) => ({...acc, [key]: orig[key]}), {})
使用法:
pick({ model : 'F40', manufacturer: 'Ferrari', productionYear: 1987 }, 'model', 'productionYear')
結果は:
{model: "F40", productionYear: 1987}
Object.assign
。ES6は、その下に非常に多くのプレゼントをクリスマスツリーのようなものです私はまだ休日後のギフトの数ヶ月探しています