如何在 ES6 中使用其值过滤对象

Posted

技术标签:

【中文标题】如何在 ES6 中使用其值过滤对象【英文标题】:How to filter an object with its values in ES6 【发布时间】:2017-10-16 23:35:26 【问题描述】:

在 ES6 中以这种方式过滤对象的最佳方法是什么?

起始数据:

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

预期输出:

filteredObject = 
    prop1:"value1",
    prop3:"value3"

【问题讨论】:

最好的方法是什么?一个简单的对象属性循环就可以了。 如果可能,尝试捕获已接受的键而不是值以简化此操作。 主要是在效率方面。一个简单的循环确实可以解决问题,但是 ES6 和“现代”数组方法可以使它更容易。 .reduce() 的答案就是 imo 的一个很好的例子。 最好的方法?不要从一开始就使用Object(而是Array)。 【参考方案1】:

对于 ES6,如果您需要静态代码(您确切知道需要过滤哪些属性)并且它不依赖于应用程序状态,那么您可以使用以下解构技术:

const myObject = 
  prop1: 'value1',
  prop2: 'value2',
  prop3: 'value3'

const  prop2, ...filteredObject  = myObject

console.info( filteredObject, prop2 )

你将拥有:

filteredObject: prop1: "value1", prop3: "value3"
prop2: "value2"

【讨论】:

【参考方案2】:

因为我还没有看到使用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)));

【讨论】:

【参考方案3】:

IMO,“最好的方式”是 Lodash 方式

const filtered = _.pick(myObject, acceptedValues)

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

【讨论】:

刚刚看了你的一个视频 .. fireship 太棒了!【参考方案4】:

只是在@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 也不能胜任这项工作,但我想提供另一种观点。

【讨论】:

【参考方案5】:
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);

【讨论】:

【参考方案6】:

使用简单的 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]);
  

【讨论】:

【参考方案7】:

为什么不是一个简单的 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);

【讨论】:

【参考方案8】:

您可以使用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)

【讨论】:

您能否解释一下为什么当我有对象时在这种情况下使用.filter 不起作用? this.activeUsers = window.users.filter( function(user) // return ( (user.test === '0') &amp;&amp; (user.isok === '0') ); return user.user_id === 1; ); 收到错误 .filter is not a function @W.Doch 因为过滤器不适用于对象,仅适用于数组

以上是关于如何在 ES6 中使用其值过滤对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Javascript/Lodash/ES6 中同时搜索父对象和子对象?

如何在限制过滤器中动态分配变量并递增/递减其值?

ES6深度解析-Classes

html5如何让边框发光

如何在 Access SQL 中使用 BETWEEN 和 AND 来过滤日期范围?

如何在python中同时使用applymap、lambda和dataframe来过滤/修改dataframe?