ECMAScript 5有数组类型的filter()原型,但没有对象类型,如果我理解正确的话。

我如何在JavaScript中实现对象的过滤器()?

假设我有这个对象:

var foo = {
    bar: "Yes"
};

我想写一个过滤器(),工作在对象:

Object.prototype.filter = function(predicate) {
    var result = {};

    for (key in this) {
        if (this.hasOwnProperty(key) && !predicate(this[key])) {
            result[key] = this[key];
        }
    }

    return result;
};

当我在下面的演示中使用它时,这是有效的,但是当我将它添加到使用jQuery 1.5和jQuery UI 1.8.9的站点时,我在FireBug中得到JavaScript错误。

Object.prototype.filter = function(predicate) { var result = {}; for (key in this) { if (this.hasOwnProperty(key) && !predicate(this[key])) { console.log("copying"); result[key] = this[key]; } } return result; }; var foo = { bar: "Yes", moo: undefined }; foo = foo.filter(function(property) { return typeof property === "undefined"; }); document.getElementById('disp').innerHTML = JSON.stringify(foo, undefined, ' '); console.log(foo); #disp { white-space: pre; font-family: monospace } <div id="disp"></div>


当前回答

如果你不需要原始对象,这是一个简单的,非常无聊的答案,不浪费内存:

const obj = {'a': 'want this', 'b': 'want this too', 'x': 'remove this'}
const keep = new Set(['a', 'b', 'c'])

function filterObject(obj, keep) {
  Object.keys(obj).forEach(key => {
    if (!keep.has(key)) {
      delete obj[key]
    }
  })
}

如果只过滤少量对象,并且对象没有很多键,则可能不想构造Set,在这种情况下使用数组。Includes而不是set.has。

其他回答

从2020年开始,香草JS解决方案。


let romNumbers={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}

你可以通过键来过滤romNumbers对象:

const filteredByKey = Object.fromEntries(
    Object.entries(romNumbers).filter(([key, value]) => key === 'I') )
// filteredByKey = {I: 1} 

或者根据值过滤romNumbers对象:

 const filteredByValue = Object.fromEntries(
    Object.entries(romNumbers).filter(([key, value]) => value === 5) )
 // filteredByValue = {V: 5} 

如何:

function filterObj(keys, obj) {
  const newObj = {};
  for (let key in obj) {
    if (keys.includes(key)) {
      newObj[key] = obj[key];
    }
  }
  return newObj;
}

还是……

function filterObj(keys, obj) {
  const newObj = {};
  Object.keys(obj).forEach(key => {
    if (keys.includes(key)) {
      newObj[key] = obj[key];
    }
  });
  return newObj;
}

如果您希望改变相同的对象,而不是创建一个新的对象。

下面的例子将删除所有0或空值:

const sev = { a: 1, b: 0, c: 3 };
const deleteKeysBy = (obj, predicate) =>
  Object.keys(obj)
    .forEach( (key) => {
      if (predicate(obj[key])) {
        delete(obj[key]);
      }
    });

deleteKeysBy(sev, val => !val);

普通 ES6:

var foo = {
    bar: "Yes"
};

const res = Object.keys(foo).filter(i => foo[i] === 'Yes')

console.log(res)
// ["bar"]

在这些情况下,我使用jquery $。映射,它可以处理对象。正如在其他回答中提到的,更改本地原型并不是一个好的实践(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Bad_practice_Extension_of_native_prototypes)

下面是一个仅通过检查对象的某些属性进行过滤的示例。如果你的条件为真,它返回自己的对象,否则返回undefined。undefined属性将使该记录从对象列表中消失;

$.map(yourObject, (el, index)=>{
    return el.yourProperty ? el : undefined;
});