web-dev-qa-db-ja.com

ES6でオブジェクトをその値でフィルタリングする方法

ES6でこのようにオブジェクトをフィルタリングする最良の方法は何ですか?

開始データ:

const acceptedValues = ["value1","value3"]
const myObject = {
    prop1:"value1",
    prop2:"value2",
    prop3:"value3"
}

予想される出力:

filteredObject = {
    prop1:"value1",
    prop3:"value3"
}
10
saawsann

reduce()を使用して新しいオブジェクトを作成し、includes()を使用してオブジェクトの値が配列に存在するかどうかを確認できます。

const acceptedValues = ["value1", "value3"]
const myObject = {
  prop1: "value1",
  prop2: "value2",
  prop3: "value3"
}

var filteredObject = Object.keys(myObject).reduce(function(r, e) {
  if (acceptedValues.includes(myObject[e])) r[e] = myObject[e]
  return r;
}, {})

console.log(filteredObject)
12
Nenad Vracar

@Nenad Vracarの良い答えの上に構築するためだけに、配列の代わりにincludesを使用してオブジェクトを使用し、検索を高速化できます。

const acceptedValues = ["value1", "value3"];
const myObject = {
  prop1: "value1",
  prop2: "value2",
  prop3: "value3"
};

const lookup = acceptedValues.reduce( (memo, prop) => {
  memo[prop] = true;
  return memo;
});

const filteredObject = Object.keys(myObject).reduce((filtered, key) => {
  if(lookup[myObject[key]]){
    filtered[key] = myObject[key];
  }
  return filtered;
}, {});

console.log(filteredObject);

includesが機能しないこともありませんが、別の見方をすると考えました。

3
MarcoL

なぜ単純なforループではないのですか?

const acceptedValues = ["value1","value3"]
const myObject = {
    prop1:"value1",
    prop2:"value2",
    prop3:"value3"
};
var  filteredObject = {};
for(e in myObject) {
    if (myObject.hasOwnProperty(e)) {
      if (acceptedValues.indexOf(myObject[e]) != -1) {
          filteredObject[e] = myObject[e];
      }
    }
}
console.log(filteredObject);
2
gaetanoM

明確なES6静的コードが必要で(正確には、どのプロパティをフィルタリングする必要があるかがわかっています)、アプリの状態に依存しない場合は、次の構造化表記を使用できます。

const myObject = {
  prop1: 'value1',
  prop2: 'value2',
  prop3: 'value3'
}
const { prop2, ...filteredObject } = myObject

console.info({ filteredObject, prop2 })

そしてあなたは:

prop2 === "value2"
filteredObject === {prop1: "value1", prop3: "value3"}
1
Roman

IMO、「最良の方法」はロダッシュの方法です

const filtered = _.pick(myObject, acceptedValues)

https://lodash.com/docs/4.17.10#pick

0
JeffD23

_Object.entries_を使用した回答を見たことがないので、こちらをご覧ください。 Object.entries()の実装はObject.keys()よりも大幅に遅いため、これも受け入れられた回答よりも遅くなりますが、読みやすさや拡張性のためにこれを好む場合があります(別のフィルタリングを通過する方が簡単です)関数)。

_const acceptedValues = ["value1", "value3"];
const myObject = {
    prop1:"value1",
    prop2:"value2",
    prop3:"value3"
};
const filteredEntries = Object.entries(myObject).filter(([, v]) => acceptedValues.includes(v));
const filteredObject = Object.fromEntries(filteredEntries);
_

または長めのワンライナーとして:

_const filteredObject = Object.fromEntries(Object.entries(myObject).filter(([, v]) => accepted.includes(v)));
_
0
naktinis

単純なforループを使用して、キーでオブジェクトを取得します。

const acceptedValues = ["value1","value3"]
const myObject = {
    prop1:"value1",
    prop2:"value2",
    prop3:"value3"
}

Object.prototype.getKeyByValue = function( value ) {
    for( var prop in this ) {
        if( this.hasOwnProperty( prop ) ) {
             if( this[ prop ] === value )
                 return prop;
        }
    }
}

for (var i in acceptedValues) {
  if (myObject.getKeyByValue(acceptedValues[i])){
    console.log(acceptedValues[i]);
  }
}
0
Idan
function filter(myObject){
  var obj=Object.assign({},myObject);
  Object.keys(obj).forEach(function(key) {
      if(acceptedValues.indexOf(obj[key])<0) delete obj[key];
  });
  return obj;
}
const filteredObject=filter(myObject);
0
DJ Yadav