Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

javascript - How to filter Object using Array.prototype.filter?

Given

var arr = [1,2,true,4,{"abc":123},6,7,{"def":456},9,[10]]

we can filter number items within array arr using Number constructor

var res = arr.filter(Number); // [1, 2, true, 4, 6, 7, 9, Array[1]]

are true and [10] expected in resulting array ? If we substitute false for true at arr

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]]

using Array.isArray

var res = arr.filter(Array.isArray) // [Array[1]]

String

var res = arr.filter(String) // [1, 2, true, 4, Object, 6, 7, Object, 9, Array[1]]

If we want to filter items within arr that are object, at indexes 4 , 7 and we try

var res = arr.filter(Object) // [1, 2, true, 4, Object, 6, 7, Object, 9, Array[1]]

Although we would prefer to simply call arr.filter(Object), we could pass a function call; trying different properties of Object so that we can eventually find a property or method that we could use as a function or constructor to pass to as the pattern arr.filter(/* method, constructor, other approach */) to return the filtered results matching the object, or even property name or value of the object within the input array.

We start, innocently enough, by checking if the item in the array has a constructor having name equal to "Object"

 var res = arr.filter(function(prop) {
  return prop.constructor.name === "Object"
 }) // [Object, Object]

though when we add an object to arr; e.g.;

 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`

as c prototype and constructor are undefined. Although we are certain that this will not return expected results

var n = arr.filter(Object.hasOwnProperty, "abc"); // [1, 2]

at least an error was not returned; let us continue

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

the expected results are returned; though we are trying to use

var n = arr.filter(/* function reference */, this /* optional parameters passed */)

to

  1. filter an array for Object : {} objects; even if the object does not have a defined prototype or constructor; optionally converting JSON string "{"abc":123}" to object; though we have not reached this far, yet;

  2. pass a property name to .filter(callback, this) pattern where this serves as property name, or value of object; or utilize an approach using filter.bind , .call or .apply or other method to filter an object from the input array - without using full

    .filter(function(prop, value) {})

    pattern. How can we coerce the Object.hasOwnProperty() call into a pattern similar to

    .filter(Object.hasOwnProperty, "abc")

?

Mentioning .call, .bind and .apply after searching for a similar Question and finding JS Array.prototype.filter on prototype method . Though not certain how to implement approaches described in filtering both objects and objects having specific properties as described above.

Note, Question can also be resolved by a destructuring , or other es-6, es-7 approach, providing comparable or, even stricter results, when compared to .filter(). That is, use .filter() without

   function(prop, value) {

   }

pattern. Returning objects; that is Object , {} ; and objects filtered by property ; objects filtered by property value.


Questions:

  1. How to filter objects with or without Object prototype or constructor within in an array passed to Array.prototype.filter() without using an anonymous function callbackpattern ?

  2. How to filter specific objects within an array passed to Array.prototype.filter() by passing property name or value to match object without using anonymous function callback pattern ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

How to filter objects with or without Object prototype or constructor within in an array passed to Array.prototype.filter() without using an anonymous function callbackpattern ?

As per spec

callbackfn should be a function that accepts three arguments and returns a value that is coercible to the Boolean value true or false

Number object (function's constructor) does return NaN for bad Number conversion but String and Object constructors don't return a false value (yes, filter(Number) also filters out 0)

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]]

You can create a customer function OBJ,

function OBJ(value,index,arr){ return typeof value === "object" && !Array.isArray(value) }

or Arrays are also welcome in the resultset then remove the Array.isArray check

function OBJ(value,index,arr){ return typeof value === "object" }

when used with

arr.filter(OBJ); //outputs [{"abc":123},{"def":456}]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...