私はフラットなJSオブジェクトを持っています:
{a: 1, b: 2, c: 3, ..., z:26}
1つの要素を除いてオブジェクトを複製したいです。
{a: 1, c: 3, ..., z:26}
これを行う最も簡単な方法は何ですか(できればes6/7を使用することを好む)。
Babel を使用する場合は、 xに含まれるプロパティbを変数bにコピーし、残りのプロパティを変数y にコピーするために次の構文を使用できます。
let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;
そして それは翻訳されます
"use strict";
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
var x = { a: 1, b: 2, c: 3, z: 26 };
var b = x.b;
var y = _objectWithoutProperties(x, ["b"]);
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;
未定義のプロパティを受け入れる場合
var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
Ilya Palkinの答えをさらに追加するには、動的にキーを削除することもできます。
const x = {a: 1, b: 2, c: 3, z:26};
const objectWithoutKey = (object, key) => {
const {[key]: deletedKey, ...otherKeys} = object;
return otherKeys;
}
console.log(objectWithoutKey(x, 'b')); // {a: 1, c: 3, z:26}
console.log(x); // {a: 1, b: 2, c: 3, z:26};
ソース:
ES6を使用できない人には、lodash
またはunderscore
を使用できます。
_.omit(x, 'b')
またはramda
。
R.omit('b', x)
単純なヘルパー関数を書くことができます。 Lodashは同じ名前の同じような機能を持っています: omit
function omit(obj, omitKey) {
return Object.keys(obj).reduce((result, key) => {
if(key !== omitKey) {
result[key] = obj[key];
}
return result;
}, {});
}
omit({a: 1, b: 2, c: 3}, 'c') // {a: 1, b: 2}
また、Object.assignよりも速いことに注意して削除してください。 http://jsperf.com/omit-key
私はこのワンライナーES6構文を使います、
const obj = {a: 1, b: 2, c: 3, d: 4};
const clone = (({b, c, ...others}) => ({...others}))(obj); // remove b and c
console.log(clone);
多分このようなもの:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
これで十分ですか。それともc
を実際にコピーすることはできませんか?
オブジェクトをコピーしてからプロパティを削除しようとしているときに、参照して問題を参照しているようです。 javascriptが新しい値を作るように、どこかでプリミティブ変数を割り当てなければなりません。
私が使った単純なトリック(恐ろしいかもしれません)はこれでした
var obj = {"key1":"value1","key2":"value2","key3":"value3"};
// assign it as a new variable for javascript to cache
var copy = JSON.stringify(obj);
// reconstitute as an object
copy = JSON.parse(copy);
// now you can safely run delete on the copy with completely new values
delete copy.key2
console.log(obj)
// output: {key1: "value1", key2: "value2", key3: "value3"}
console.log(copy)
// output: {key1: "value1", key3: "value3"}
Lodash 省略
let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
これはどうですか?私はこのパターンを見つけることはできませんでしたが、余分なオブジェクトを作成する必要なしに1つ以上のプロパティを除外しようとしていました。これは仕事をしているようですが、私が見ることができないいくつかの副作用があります。確かに非常に読みやすいではありません。
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
オブジェクト構造化の使用
const omit = (prop, { [prop]: _, ...rest }) => rest;
const obj = { a: 1, b: 2, c: 3 };
const objWithoutA = omit('a', obj);
console.log(objWithoutA); // {b: 2, c: 3}
巨大な変数を扱っているのであれば、コピーしてから削除することは望ましくありません。これは非効率的です。
HasOwnPropertyチェックを使った単純なforループでうまくいくはずです。将来のニーズにもっと適応できるでしょう。
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
これを行うために、スプレッド演算子を使用することもできます。
const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
私は最近この非常に簡単な方法でそれをしました:
const obj = {a: 1, b: 2, ..., z:26};
スプレッド演算子 を使用して不要なプロパティを分離します。
const {b, ...rest} = obj;
...および object.assign 「残りの部分」のみを取得します。
const newObj = Object.assign({}, {...rest});
私のReduxリデューサーの例として、私はこれを達成しました。
const clone = { ...state };
delete clone[action.id];
return clone;
言い換えると:
const clone = { ...originalObject } // note: original object is not altered
delete clone[unwantedKey] // or use clone.unwantedKey or any other applicable syntax
return clone // the original object without the unwanted key
これも実行する必要があります。連想配列でも「削除」が機能すると確信しています:
var copy = (obj, del)=>{
delete obj.del;
return obj;
}
上記の構造化を使用した解決策は、used変数を使用しているという事実に悩まされています。これを使用していると、ESLintから苦情が発生する可能性があります。
だからここに私の解決策があります:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
ほとんどのプラットフォーム(Babelを使わない限りIEを除く)では、次のこともできます。
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))