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>


当前回答

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

下面的例子将删除所有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);

其他回答

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

下面的例子将删除所有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);

我已经创建了一个Object.filter(),它不仅通过一个函数进行筛选,而且还接受一个包含键的数组。可选的第三个参数将允许反转筛选器。

考虑到:

var foo = {
    x: 1,
    y: 0,
    z: -1,
    a: 'Hello',
    b: 'World'
}

数组:

Object.filter(foo, ['z', 'a', 'b'], true);

功能:

Object.filter(foo, function (key, value) {
    return Ext.isString(value);
});

Code

免责声明:为了简洁起见,我选择使用Ext JS核心。我觉得没有必要为对象类型编写类型检查器,因为这不是问题的一部分。

// Helper function function print(obj) { document.getElementById('disp').innerHTML += JSON.stringify(obj, undefined, ' ') + '<br />'; console.log(obj); } Object.filter = function (obj, ignore, invert) { let result = {}; // Returns a filtered copy of the original list if (ignore === undefined) { return obj; } invert = invert || false; let not = function(condition, yes) { return yes ? !condition : condition; }; let isArray = Ext.isArray(ignore); for (var key in obj) { if (obj.hasOwnProperty(key) && !(isArray && not(!Ext.Array.contains(ignore, key), invert)) && !(!isArray && not(!ignore.call(undefined, key, obj[key]), invert))) { result[key] = obj[key]; } } return result; }; let foo = { x: 1, y: 0, z: -1, a: 'Hello', b: 'World' }; print(Object.filter(foo, ['z', 'a', 'b'], true)); print(Object.filter(foo, (key, value) => Ext.isString(value))); #disp { white-space: pre; font-family: monospace } <script src="https://cdnjs.cloudflare.com/ajax/libs/extjs/4.2.1/builds/ext-core.min.js"></script> <div id="disp"></div>

您还可以执行类似的操作,对条目进行筛选,以找到提供的键并返回值

   let func = function(items){
      let val
      Object.entries(this.items).map(k => {
        if(k[0]===kind){
         val = k[1]
        }
      })
      return val
   }

ES6进近...

假设你有下面这个对象:

const developers = {
  1: {
   id: 1,
   name: "Brendan", 
   family: "Eich"
  },
  2: {
   id: 2,
   name: "John", 
   family: "Resig"
  },  
  3: {
   id: 3,
   name: "Alireza", 
   family: "Dezfoolian"
 }
};

创建一个函数:

const filterObject = (obj, filter, filterValue) => 
   Object.keys(obj).reduce((acc, val) => 
   (obj[val][filter] === filterValue ? acc : {
       ...acc,
       [val]: obj[val]
   }                                        
), {});

叫它:

filterObject(developers, "name", "Alireza");

并将返回:

{
  1: {
  id: 1,
  name: "Brendan", 
  family: "Eich"
  },
  2: {
   id: 2,
   name: "John", 
   family: "Resig"
  }
}

就像所有人说的,不要在原型上做文章。相反,只需编写一个函数来执行此操作。以下是我使用lodash的版本:

import each from 'lodash/each';
import get from 'lodash/get';

const myFilteredResults = results => {
  const filteredResults = [];

  each(results, obj => {
    // filter by whatever logic you want.

    // sample example
    const someBoolean = get(obj, 'some_boolean', '');

    if (someBoolean) {
      filteredResults.push(obj);
    }
  });

  return filteredResults;
};