web-dev-qa-db-ja.com

1つのキーを除いてjsオブジェクトを複製する

私はフラットなJSオブジェクトを持っています:

{a: 1, b: 2, c: 3, ..., z:26}

1つの要素を除いてオブジェクトを複製したいです。

{a: 1, c: 3, ..., z:26}

これを行う最も簡単な方法は何ですか(できればes6/7を使用することを好む)。

185
fox

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"]);
276
Ilya Palkin
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});
100
madox2

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};

BabelでのデモREPL

ソース:

53
Paul Kögel

ES6を使用できない人には、lodashまたはunderscoreを使用できます。

_.omit(x, 'b')

またはramda

R.omit('b', x)
49
dashmug

単純なヘルパー関数を書くことができます。 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

18
just-boris

私はこのワンライナー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);
12
vdegenne

多分このようなもの:

var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;

これで十分ですか。それともcを実際にコピーすることはできませんか?

9
clean_coding

オブジェクトをコピーしてからプロパティを削除しようとしているときに、参照して問題を参照しているようです。 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"}
6
Chris Fust

Lodash 省略

let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
4
OscarRyz

これはどうですか?私はこのパターンを見つけることはできませんでしたが、余分なオブジェクトを作成する必要なしに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,
}
*/
2
andreasonny83

オブジェクト構造化の使用

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}
2
Ivan Nosov

巨大な変数を扱っているのであれば、コピーしてから削除することは望ましくありません。これは非効率的です。

HasOwnPropertyチェックを使った単純なforループでうまくいくはずです。将来のニーズにもっと適応できるでしょう。

for(var key in someObject) {
        if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
                copyOfObject[key] = someObject[key];
        }
}
2
HoldOffHunger

これを行うために、スプレッド演算子を使用することもできます。

const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
2
Mickael M.

私は最近この非常に簡単な方法でそれをしました:

const obj = {a: 1, b: 2, ..., z:26};

スプレッド演算子 を使用して不要なプロパティを分離します。

const {b, ...rest} = obj;

...および object.assign 「残りの部分」のみを取得します。

const newObj = Object.assign({}, {...rest});
2
Pepdbm 7

私の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
1
Jonathan Tuzman

これも実行する必要があります。連想配列でも「削除」が機能すると確信しています:

var copy = (obj, del)=>{
    delete obj.del;
    return obj;
}
0
Raphael Spoerri

上記の構造化を使用した解決策は、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'))
0
bert bruynooghe