Javascript filter vs проблема с картой

В качестве продолжения моего min/max для массива объектов мне было интересно узнать о сравнении производительности фильтра и карты.

Итак, я собрал тест на значения в моем коде, чтобы посмотреть результаты в FireBug.

Это код:

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"]; }));

Версия версии map возвращает правильный результат. Однако версия filter ed возвращает NaN. Выйдя из него, пройдя и, наконец, проверив результаты, окажется, что внутренняя функция возвращает свойство x _vec, но фактический массив, возвращаемый из filter, является нефильтрованным _vec.

Я считаю, что мое использование filter верное - может ли кто-нибудь еще увидеть мою проблему?

Вот простой тест:

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

Ответ 1

Нет, метод filter не возвращает нефильтрованный массив. Он возвращает массив, содержащий элементы, где внутренняя функция возвращает true.

Поскольку вы не возвращаете логическое значение из внутренней функции, значение преобразуется в значение boolean, поэтому ссылка объекта преобразуется в true. Таким образом, он возвращает новый массив, содержащий все элементы из исходного массива.

Метод filter не выполняет то же самое, что и метод map. Метод map используется для преобразования каждого элемента массива, а метод filter используется для выбора определенных элементов массива. Сравнение производительности между методами является спорным, поскольку только один из них делает то, что вы хотите сделать.

Ответ 2

Цитата из:

JavaScript: окончательное руководство
Дэвид Фланаган

карта()

Метод map() передает каждый элемент массива, на котором он вызывается для указанной вами функции и возвращает массив, содержащий значения, возвращаемые этой функцией.

Например:

a = [1, 2, 3];

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

Функция, которую вы передаете map(), вызывается так же, как и функция передана для forEach(). Однако для метода map() функция, которую вы передаете, должна возвращать значение. Обратите внимание, что map() возвращает новый array: он не изменяет массив, на который он вызывается. Если этот массив разреженный массив будет редким так же: он будет имеют ту же длину и те же недостающие элементы.

фильтр()

Метод возвращает массив, содержащий подмножество элементов массив, на который он вызывается. Функция, которую вы передаете ей, должна быть predicate: функция, которая возвращает true или false. Предикат вызывается так же, как для forEach() и map(). Если возвращаемое значение истинно, или значение, которое преобразуется в true, тогда элемент, переданный в предикат является членом подмножества и добавляется к массиву, который станет возвращаемым значением.

<сильные > Примеры:

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]