配列内のすべてのオブジェクトのプロパティを削除します


109

bad配列内のすべてのオブジェクトからプロパティを削除したいと思います。forループを使用してすべてのオブジェクトから削除するよりも良い方法はありますか?

var array = [{"bad": "something", "good":"something"},{"bad":"something", "good":"something"},...];

for (var i = 0, len = array.length; i < len; i++) {
  delete array[i].bad;
}

prototype、または何かを使用する方法があるはずのようです。知りません。アイデア?


1
関係ありません、他の方法は線形O(n)よりも少なくなることはできません。使用するものが何であれ、すべての配列要素にアクセスする必要があります
Brian

プロトタイプ?それはどのように役立ちますか?または、これらすべてのオブジェクトは同じコンストラクターのインスタンスであり、bad?の共通の値を共有していますか?
ベルギ2013

1
@Bergi彼らがprototypeJSを参照しているのか、Arrayそれともdystroyが例示したプロトタイプを参照しているのだろうか
Ian

ループする前にarray.lengthを変数に格納する必要があるかどうかはわかりません。あなたがプロファイリングすれば、それは苦痛の価値がないことがわかると確信しています。
デニス・Séguret

1
@ZackArgyleはい、一般的なケースでは、これ以上速いものはありません。
デニス・Séguret

回答:


119

他の唯一の方法は表面的なものであり、実際にはループです。

例えば ​​:

array.forEach(function(v){ delete v.bad });

ノート:

  • IE8との互換性が必要な場合は、forEachのシムが必要になります。プロトタイプについておっしゃるように、prototype.jsにもシムがあります。
  • delete最悪の「最適化キラー」の1つです。これを使用すると、アプリケーションのパフォーマンスが低下することがよくあります。プロパティを実際に削除したい場合は回避できませんが、多くの場合、プロパティをに設定するか、プロパティundefinedなしで新しいオブジェクトを作成することができます。

1
ループが「偽物」であることが許可されている場合、ループよりもはるかに優れているわけではありませんfor(var i = 0; i < array.length ) delete array[i].bad
-1

1
@Esailija依存します。私forEachはコードがより表現力豊かであると思うので(そして私がずっと前にIEについて心配するのをやめたので)使うのが好きです。
デニス・Séguret

1
どちらも、「この配列内のすべてのオブジェクトの不正なプロパティを削除する」ことを根本的に異なる方法で表現していません。ループのforEachように、それ自体は一般的で意味的に無意味forです。
Esailija 2013

1
@Esailija同意します。だから私はそれが「化粧品」であると正確に述べました。私の答えでははっきりしていませんか?
デニス・Séguret

残念ながら。一般的にforEachよりも高速なforループを使用します。そして本当に... IE8を気にする人。助けてくれてありがとう。
ザックアーガイル2013

173

ES6では、各オブジェクトを分解して、名前付き属性のない新しいオブジェクトを作成できます。

const newArray = array.map(({dropAttr1, dropAttr2, ...keepAttrs}) => keepAttrs)

16
最初の問題に適用すると、次のようになりますconst newArray = array.map(({ bad, ...item }) => item);
2018

1
それは元の配列(不変の操作)を変更していないので、これは非常にお勧めします
ピチカート

1
これは、既存の配列を上書きするのではなく、新しい配列を返すため、受け入れられる答えになるはずです。
user12751 0519

偉大な答えはなく動作していないプロパティ名にドットが含まれている場合たとえば、「bad.prop」(。)
ヤヤッティ

@Amiraslan私が使用する// eslint-disable-next-line no-unused-vars
piotr_cz

20

mapを使用してプロパティを削除してから、新しい配列アイテムを返すことを好みます。

array.map(function(item) { 
    delete item.bad; 
    return item; 
});

12
これにより元の配列が変更されることに注意してください
piotr_cz 2017年

1
この特定のケースでは、明示的なreturnステートメントは必要ありません
SandeepKumar19年

4
array.forEach(v => delete v.bad);
AnthonyAwuley19年


9

プロトタイプを使用した解決策は、オブジェクトが類似している場合にのみ可能です。

function Cons(g) { this.good = g; }
Cons.prototype.bad = "something common";
var array = [new Cons("something 1"), new Cons("something 2"), …];

しかし、それは簡単です(そしてO(1)):

delete Cons.prototype.bad;

3

私の意見では、これは最も単純なバリアントです

array.map(({good}) => ({good}))

3
問題は、良いものを維持するのではなく、悪いものを取り除くことでした。オブジェクトに保持するフィールドが10個、削除するフィールドが1個ある場合、上記の入力は非常に長くなります。
エイドリアン

1

あなたはこれに従うことができます、より読みやすく、キーが見つからないために期待が上がることはありません:

data.map((datum)=>{
                    return {
                        'id':datum.id,
                        'title':datum.login,
                    }

0

オブジェクトがコピーされ、オブジェクトの元の配列に影響を与えないようにObject.assignforEach()ループ内で使用することをお勧めします

var res = [];
array.forEach(function(item) { 
    var tempItem = Object.assign({}, item);
    delete tempItem.bad; 
    res.push(tempItem);
});
console.log(res);

0

この質問は少し古くなっていますが、ソースデータを変更せず、最小限の手動作業で済む代替ソリューションを提供したいと思います。

function mapOut(sourceObject, removeKeys = []) {
  const sourceKeys = Object.keys(sourceObject);
  const returnKeys = sourceKeys.filter(k => !removeKeys.includes(k));
  let returnObject = {};
  returnKeys.forEach(k => {
    returnObject[k] = sourceObject[k];
  });
  return returnObject;
}

const array = [
  {"bad": "something", "good":"something"},
  {"bad":"something", "good":"something"},
];

const newArray = array.map(obj => mapOut(obj, [ "bad", ]));

それでも完全には少し劣りますが、ある程度の不変性を維持し、削除する複数のプロパティに名前を付ける柔軟性があります。(提案を歓迎します)


0

Vue.jsの列を削除せずに、新しいオブジェクトを作成してみました。

let data =this.selectedContactsDto[];

// selectedContactsDto [] =プロジェクトで作成された配列オブジェクトのリストを持つオブジェクト

console.log(data); newDataObj = data.map(({groupsList、customFields、firstname、... item})=> item); console.log( "newDataObj"、newDataObj);


0

一部のキーと値のペアを削除するには、オブジェクト配列は次の例のようにデータベースとしてPostgresSQLを使用します。

これはユーザー関数returnuser detailsオブジェクトであり、行から「api_secret」キーを削除する必要があります。

    function getCurrentUser(req, res, next) { // user function
    var userId = res.locals.userId;
    console.log(userId)
    db.runSQLWithParams("select * from users where id = $1", [userId], function(err, rows) {
      if(err){
        console.log(err)
      }
      var responseObject = {
        _embedded: rows,
      }
      responseObject._embedded[0].api_secret = undefined
      // console.log(api);
      // console.log(responseObject);
      res.json(responseObject);
    }); 
}

上記の関数は、前にJSON応答としてオブジェクトの下に戻ります

 {
    "_embedded": [
        {
            "id": "0123abd-345gfhgjf-dajd4456kkdj",
            "secret_key: "secret",
            "email": "abcd@email.com",
            "created": "2020-08-18T00:13:16.077Z"
        }
    ]
}

この行を追加した後responseObject._embedded[0].api_secret = undefined、JSON応答として以下の結果が得られます。

{
        "_embedded": [
            {
                "id": "0123abd-345gfhgjf-dajd4456kkdj",
                "email": "abcd@email.com",
                "created": "2020-08-18T00:13:16.077Z"
            }
        ]
    }


-4

var array = [{"bad": "something", "good":"something"},{"bad":"something", "good":"something"}];
var results = array.map(function(item){
  return {good : item["good"]}
});
console.log(JSON.stringify(results));


あなたの解決策を説明してもらえますか?
sg7 2018

Mapは、JavaScriptES6の新しいデータ構造です。添付のリンクが役立つ場合があります。hackernoon.com/what-you-should-know-about-es6-maps-dc66af6b9a1e
hk_y

アイテムに多くの小道具がある場合、このソリューションは適切ではありません。
koop4 2018

はい!別のアプローチを提供しようとしました。
hk_y
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.