ECMAScript 5 имеет filter()
прототип для Array
типов, но не для Object
типов, если я правильно понимаю.
Как бы я реализовать filter()
для Object
s в JavaScript?
Допустим, у меня есть этот объект:
var foo = {
bar: "Yes"
};
И я хочу написать, filter()
что работает на Object
с:
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, я получаю ошибки JavaScript в FireBug.
javascript
jquery
object
filtering
AgileMeansDoAsLittleAsPossible
источник
источник
Object.prototype
: bugs.jquery.com/ticket/2721Ответы:
Никогда не расширяйся
Object.prototype
.Ужасные вещи будут происходить с вашим кодом. Вещи сломаются. Вы расширяете все типы объектов, включая литералы объектов.
Вот быстрый пример, который вы можете попробовать:
Вместо этого создайте функцию, которую вы передаете объекту.
источник
Object.prototype
, а просто вложить функциюObject
. Во-вторых, это код ОП . Ясно, что намерение ОП состоит в том, чтобы иметь.filter()
возможность отфильтровывать положительные результаты. Другими словами, это отрицательный фильтр, где положительное возвращаемое значение означает, что оно исключено из результата. Если вы посмотрите на пример jsFiddle, он отфильтровывает существующие свойстваundefined
.Object.prototype
. Из вопроса: «Это работает ..., но когда я добавляю его на свой сайт ..., я получаю ошибки JavaScript». Если OP решит реализовать a.filter()
с поведением, противоположным таковомуArray.prototpe.filter
, это его / ее. Пожалуйста, оставьте комментарий под вопросом, если вы хотите уведомить OP, что код неправильный, но не говорите мне, что я делаю это неправильно, если это не мой код.Прежде всего, расширение считается плохой практикой
Object.prototype
. Вместо этого, обеспечить вашу функцию в качестве функции полезности наObject
, так же , как там уже естьObject.keys
,Object.assign
,Object.is
... и т.д..Я приведу здесь несколько решений:
reduce
иObject.keys
Object.assign
map
и распространение синтаксиса вместоreduce
Object.entries
иObject.fromEntries
1. Использование
reduce
иObject.keys
С помощью
reduce
иObject.keys
реализовать желаемый фильтр (используя синтаксис стрелки ES6 ):Обратите внимание, что в приведенном выше коде
predicate
должно быть условие включения (в отличие от условия исключения используемого OP), чтобы оно соответствовало тому, какArray.prototype.filter
работает.2. Как (1), в сочетании с
Object.assign
В приведенном выше решении оператор запятой используется в
reduce
части для возврата мутированногоres
объекта. Конечно, это можно записать в виде двух утверждений вместо одного выражения, но последнее является более кратким. Для того, чтобы сделать это без оператора запятая, вы можете использоватьObject.assign
вместо этого, который действительно возвращает мутантный объект:3. Использование
map
и распространение синтаксиса вместоreduce
Здесь мы перемещаем
Object.assign
вызов из цикла, чтобы он выполнялся только один раз, и передаем отдельные ключи в качестве отдельных аргументов (используя синтаксис распространения ):4. Использование
Object.entries
иObject.fromEntries
Поскольку решение переводит объект в промежуточный массив, а затем преобразует его обратно в простой объект, было бы полезно использовать
Object.entries
(ES2017) и наоборот (т.е. создать объект из массива пар ключ / значение ) с помощьюObject.fromEntries
( ES2019).Это приводит к этому «однострочному» методу
Object
:Функция предиката получает здесь пару ключ / значение в качестве аргумента, которая немного отличается, но допускает больше возможностей в логике функции предиката.
источник
x => x.Expression.Filters.Filter
.Filter
находится в конце, но если это функция, вам нужно вызвать ее (x => x.Expression.Filters.Filter()
)Если вы хотите использовать подчеркивание или штрих , вы можете использовать
pick
(или наоборотomit
).Примеры из документов подчеркивания:
Или с обратным вызовом (для lodash используйте pickBy ):
источник
ES6 подход ...
Представьте, что у вас есть этот объект ниже:
Создать функцию:
И назовите это:
и вернется :
источник
!predicate
в их собственном коде).Как уже сказал Патрик, это плохая идея, поскольку она почти наверняка сломает любой сторонний код, который вы когда-либо захотите использовать.
Все библиотеки, такие как jquery или prototype, прервутся, если вы расширите
Object.prototype
, причина в том, что ленивая итерация над объектами (безhasOwnProperty
проверок) прервется, поскольку добавленные вами функции будут частью итерации.источник
Как насчет:
Или...
источник
Дано
затем :
Показать фрагмент кода
источник
Я создал,
Object.filter()
который не только фильтрует по функции, но также принимает массив ключей для включения. Необязательный третий параметр позволит вам инвертировать фильтр.Дано:
Массив:
Функция:
Код
отказ : я решил использовать ядро Ext JS для краткости. Не чувствовал, что было необходимо писать контролеры типов для типов объектов, поскольку это не было частью вопроса.
источник
Мое самоуверенное решение:
Тестовые случаи:
https://gist.github.com/bernardoadc/872d5a174108823159d845cc5baba337
источник
Решение в Vanilla JS с 2020 года.
Вы можете фильтровать
romNumbers
объект по ключу:Или отфильтруйте
romNumbers
объект по значению:источник
Если вы хотите изменить тот же объект, а не создавать новый.
В следующем примере будут удалены все 0 или пустые значения:
источник
Как все говорили, не облажайтесь с прототипом. Вместо этого просто напишите функцию для этого. Вот моя версия с
lodash
:источник
Я использую это, когда мне это нужно:
источник
В этих случаях я использую jquery $ .map, который может обрабатывать объекты. Как уже упоминалось в других ответах, не рекомендуется менять родные прототипы ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Bad_practice_Extension_of_native_prototypes )
Ниже приведен пример фильтрации, просто проверяя некоторые свойства вашего объекта. Он возвращает собственный объект, если ваше условие истинно, или возвращает,
undefined
если нет.undefined
Свойство будет делать , что запись исчезнет из списка объектов;источник
$.map
может взять объект, но он возвращает массив, поэтому исходные имена свойств теряются. ОП требует отфильтрованный простой объект.