简体   繁体   中英

Javascript filter vs map problem

As a continuation of my min/max across an array of objects I was wondering about the performance comparisons of filter vs map.

So I put together a test on the values in my code as was going to look at the results in FireBug.

This is the code:

var _vec = this.vec;
min_x = Math.min.apply(Math, _vec.filter(function(el){ return el["x"]; }));
min_y = Math.min.apply(Math, _vec.map(function(el){ return el["x"]; }));

The map ped version returns the correct result. However the filter ed version returns NaN. Breaking it out, stepping through and finally inspecting the results, it would appear that the inner function returns the x property of _vec but the actual array returned from filter is the unfiltered _vec .

I believe my usage of filter is correct - can anyone else see my problem?

Here's a simple test:

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>S:GTC Map Test</title>
</head>
<body>
<script type="text/javascript">
function vector(x,y,z) { this.x = x; this.y =y; this.z=z; }
var vec = [];
vec.push(new vector(1,1,1));
vec.push(new vector(2,2,2));
vec.push(new vector(2,3,3));
var _vec = vec;
min_x = Math.min.apply(Math, _vec.filter(function(el){ return el["x"]; }));
min_y = Math.min.apply(Math, _vec.map(function(el){ return el["x"]; }));

document.write("<br>filter = " + min_x);
document.write("<br>map = " + min_y);
</script>
</body>
</html>

No, the filter method doesn't return the unfiletered array. It returns an array containing the items where the inner function returns true.

As you are not returning a boolean value from the inner function, the value is converted to boolean, so the object reference is converted to true. Thus, it returns a new array that contains all the items from the original array.

The filter method doesn't do the same as the map method. The map method is used to convert each item of an array, while the filter method is used to select certain items of an array. Comparing the performance between the methods is moot, as only one of them does what you want to do.

Quoted from:

JavaScript: The Definitive Guide
by David Flanagan

map()

The map() method passes each element of the array on which it is invoked to the function you specify, and returns an array containing the values returned by that function.

For example:

 a = [1, 2, 3]; b = a.map(function(x) { return x*x; }); // b is [1, 4, 9] 

The function you pass to map() is invoked in the same way as a function passed to forEach(). For the map() method, however, the function you pass should return a value.Note that map() returns a new array: it does not modify the array it is invoked on. If that array is sparse, the returned array will be sparse in the same way: it will have the same length and the same missing elements.

filter()

The method returns an array containing a subset of the elements of the array on which it is invoked. The function you pass to it should be predicate: a function that returns true or false. The predicate is invoked just as for forEach() and map(). If the return value is true , or a value that converts to true, then the element passed to the predicate is a member of the subset and is added to the array that will become the return value.

Examples:

 a = [5, 4, 3, 2, 1]; smallvalues = a.filter(function(x) { return x < 3 }); // [2, 1] everyother = a.filter(function(x,i) { return i%2==0 }); // [5, 3, 1] 
// MAP creates a new array
// MPA return new Array
var arr = [1, 2, 3, 4, 5, 6, 7];

var newArr = arr.map((el) => {
  return el * 2;
});

console.log(newArr); //2,4,3,8,10,12,14

// filter() return new Array
var newFilter = arr.filter((el) => {
   return el * 2;
});
console.log(newFilter); // 1,2,3,4,5,6,7

now you can see I have return el*2 both for map and filter they are giving a different output

Filter() The filter() method creates a new array filled with all array elements that pass a test implemented by the function.

If this conditional returns true, the element gets pushed to the output array. If the condition returns false, the element does not get pushed to the output array.

var arr = [1, 2, 3, 4, 5, 6, 7];
var newFilter = arr.filter((el) => {
  return el > 3;
});
console.log(newFilter);  //[1, 2, 3, 4]

Map() The map() method is used for creating a new array from an existing one, applying a function to each one of the elements of the first array var arr = [1, 2, 3, 4, 5, 6, 7];

var newArr = arr.map((el) => {
  return el * 2;
});

console.log(newArr); //2,4,3,8,10,12,14

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM