首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Array.prototype.filter过滤对象?

如何使用Array.prototype.filter过滤对象?
EN

Stack Overflow用户
提问于 2016-03-26 06:57:00
回答 6查看 7.6K关注 0票数 6

给定的

代码语言:javascript
复制
var arr = [1,2,true,4,{"abc":123},6,7,{"def":456},9,[10]]

我们可以使用arr构造函数在数组Number中筛选数字项。

代码语言:javascript
复制
var res = arr.filter(Number); // [1, 2, true, 4, 6, 7, 9, Array[1]]

在结果数组中是否需要true[10]?如果我们用false代替truearr

代码语言:javascript
复制
var arr = [1,2,false,4,{"abc":123},6,7,{"def":456},9,[10]] 
var res = arr.filter(Number) // [1, 2, 4, 6, 7, 9, Array[1]]

使用Array.isArray

代码语言:javascript
复制
var res = arr.filter(Array.isArray) // [Array[1]]

String

代码语言:javascript
复制
var res = arr.filter(String) // [1, 2, true, 4, Object, 6, 7, Object, 9, Array[1]]

如果要在arr中筛选对象项,请在索引47上进行筛选,然后尝试

代码语言:javascript
复制
var res = arr.filter(Object) // [1, 2, true, 4, Object, 6, 7, Object, 9, Array[1]]

虽然我们更倾向于简单地调用arr.filter(Object),但是我们可以传递一个函数调用;尝试Object的不同属性,这样我们最终可以找到一个属性或方法,我们可以使用它作为函数或构造函数传递给模式arr.filter(/* method, constructor, other approach */),以返回与对象匹配的过滤结果,甚至可以在输入数组中找到对象的属性名或值。

我们首先从检查数组中的项是否有一个具有constructorname等于"Object"开始。

代码语言:javascript
复制
 var res = arr.filter(function(prop) {
  return prop.constructor.name === "Object"
 }) // [Object, Object]

虽然当我们在arr中添加一个对象时;例如;

代码语言:javascript
复制
 var c = Object.create(null); arr.push(c); 

 var res = arr.filter(function(prop) {
   return prop.constructor.name === "Object"
 }) // `Uncaught TypeError: Cannot read property 'name' of undefined`

就像cprototypeconstructorundefined。虽然我们确信这不会返回预期的结果

代码语言:javascript
复制
var n = arr.filter(Object.hasOwnProperty, "abc"); // [1, 2]

至少没有返回一个错误;让我们继续

代码语言:javascript
复制
var n = arr.filter(function(prop, val) {
          return prop.hasOwnProperty(this.valueOf())
        }, "abc"); // [Object abc: 123__proto__: Object]

将返回预期的结果;尽管我们正在尝试使用

代码语言:javascript
复制
var n = arr.filter(/* function reference */, this /* optional parameters passed */)

  1. 过滤Object{}对象的数组;即使对象没有定义的原型或构造函数;可选地将JSON字符串"{"abc":123}"转换为对象;
  2. 将属性名称传递给.filter(callback, this)模式,其中this充当属性名或对象值;或使用使用filter.bind.call.apply或其他方法从输入数组筛选对象的方法--而不使用完整的 .filter(function(prop, value) {}) 模式。我们如何将Object.hasOwnProperty()调用强制转换成类似于 .filter(Object.hasOwnProperty, "abc")

在搜索了一个类似的问题并找到了.call.bind.apply之后,提到了基于原型法的JS Array.prototype.filter。虽然不确定如何实现过滤中描述的方法,但如上所述,具有特定属性的对象和对象都是如此。

注意,问题也可以通过destructuring或其他es-6es-7方法来解决,与.filter()相比,可以提供可比的甚至更严格的结果。也就是说,使用.filter()时不要

代码语言:javascript
复制
   function(prop, value) {

   }

模式。返回对象;即Object{};以及按属性过滤的对象;按属性值过滤的对象。

问题:

  1. 如何在不使用匿名函数Object模式的情况下,在传递给Array.prototype.filter()的数组中筛选具有或不包含callback原型或构造函数的对象?
  2. 如何通过传递属性名称或值来匹配对象而不使用匿名函数Array.prototype.filter()模式来筛选传递给callback的数组中的特定对象?
EN

回答 6

Stack Overflow用户

发布于 2016-03-26 07:24:33

如何在不使用匿名函数回调模式的情况下筛选传递给Array.prototype.filter()的数组中的对象原型或构造函数?

根据等级库

回调or应该是一个函数,它接受三个参数,并返回一个值,该值可强制为布尔值true或false。

数字对象 (函数的构造函数)确实返回NaN进行错误的数字转换,但是字符串和对象构造函数不返回假值(是的,filter(Number)也过滤掉0)。

代码语言:javascript
复制
var arr = [0,1,2,true,4,{"abc":123},6,7,{"def":456},9,[10]];
arr.filter(Number); //outputs [1, 2, true, 4, 6, 7, 9, Array[1]]

您可以创建客户函数OBJ,

代码语言:javascript
复制
function OBJ(value,index,arr){ return typeof value === "object" && !Array.isArray(value) }

或者在结果集中也欢迎数组,然后删除Array.isArray检查。

代码语言:javascript
复制
function OBJ(value,index,arr){ return typeof value === "object" }

当与

代码语言:javascript
复制
arr.filter(OBJ); //outputs [{"abc":123},{"def":456}]
票数 2
EN

Stack Overflow用户

发布于 2016-03-26 07:50:57

在不创建自己的函数的情况下,没有真正的方法可以安全地完成它。另外,由于Object的定义过于宽泛,所以它非常复杂。

让我们从以下几个方面开始:

代码语言:javascript
复制
var types = ['1', 2, true, null, undefined, [], {}, new Date()];

并运行以下命令:

代码语言:javascript
复制
types.map((e) => typeof e);
// ["string", "number", "boolean", "object", "undefined", "object", "object", "object"]

你认为nullObject吗?我不这样认为。您认为ArrayObject吗?因为ArrayObject的一个实例?我也不确定。

您可以尝试以下几点:

代码语言:javascript
复制
types.map(Object.isExtensible);
// [false, false, false, false, false, true, true, true]

这从结果中排除了null,但是这里仍然存在数组。Date Object和任何其他带有prototypeObject都在这里,例如new Boolean()也将是Object。此外,可以冻结对象,这也不会以Object的形式返回。

因此,这里的两个示例都成功地证明了Object的定义过于宽泛,不能真正以一种有用的方式处理。

票数 2
EN

Stack Overflow用户

发布于 2016-03-26 13:16:29

您似乎希望为具有特定类型的元素筛选数组。将适当的函数传递给filter

代码语言:javascript
复制
array.filter(istype("String"))

现在只需编写istype

代码语言:javascript
复制
function istype(type) {
  return function(x) {
    return Object.prototype.toString.call(x) === '[object ' + type + ']';
  }
}

你似乎以为你可以通过说、filter(Number)等来过滤数字,但这是行不通的。Number只是另一个函数,它试图将某个东西转换成一个数字(而不是检查它是否是数字)。然后,根据结果是真实的还是错误的,filter过滤数组。显然,Number会为任何非零数生成一个真实值,而true则会产生一个真实值。对于一个字符串,或者一个对象,或者几乎任何其他的东西,它都将返回NaN,这是错误的,除了奇怪的例外,比如返回[]0或一个全空字符串。

字符串也是一样。String只是另一个函数,它试图将某些内容转换为字符串。然后,根据结果是真实的还是错误的,filter过滤数组。String将为非空字符串以外的几乎任何东西生成一个真实的值。

这和破坏没有任何关系,你为什么会这么认为呢?你可能想要删除你职位中那个不幸的部分。也不清楚你所说的“调用过滤器而没有回调”--使用回调来确定哪些元素是filter的全部。当您说function(prop, value) { }模式时,也不清楚您指的是什么模式。

在你问题的最后,你会问两个具体的问题:

如何在不使用匿名函数回调模式的情况下筛选传递给Array.prototype.filter()的数组中的对象原型或构造函数?

您可以通过提供一个函数来筛选输入数组中的对象,该函数确定特定元素是否为对象。这不是对象原型或构造器Object的特性,所以这不会对您有所帮助。您必须编写一个小函数才能传递给filter,这就是它的工作方式。它可以是匿名的,也可以在其他地方定义并传入。

如何通过传递属性名称或值来匹配对象而不使用匿名函数回调模式来筛选传递给Array.prototype.filter()的数组中的特定对象?

您所说的“传递属性名称或值以匹配对象”是什么意思?您的意思是,筛选掉缺少特定属性名称或值的元素吗?然后编写一个函数来完成这个任务。如果这是我们正在寻找的东西的话,就没有内置的功能。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36232576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档