Agi*_*ble 136 javascript jquery filtering object
如果我理解正确,ECMAScript 5有类型的filter()原型Array,但不是Object类型.
我如何在JavaScript中实现filter()for Object?
假设我有这个对象:
var foo = {
bar: "Yes"
};
Run Code Online (Sandbox Code Playgroud)
我想写一个filter()适用于Objects的:
Object.prototype.filter = function(predicate) {
var result = {};
for (key in this) {
if (this.hasOwnProperty(key) && !predicate(this[key])) {
result[key] = this[key];
}
}
return result;
};
Run Code Online (Sandbox Code Playgroud)
这在我在下面的演示中使用时有效,但是当我将它添加到使用jQuery 1.5和jQuery UI 1.8.9的网站时,我在FireBug中遇到了JavaScript错误.
Object.prototype.filter = function(predicate) {
var result = {};
for (key in this) {
if (this.hasOwnProperty(key) && !predicate(this[key])) {
console.log("copying");
result[key] = this[key];
}
}
return result;
};
var foo = {
bar: "Yes",
moo: undefined
};
foo = foo.filter(function(property) {
return typeof property === "undefined";
});
document.getElementById('disp').innerHTML = JSON.stringify(foo, undefined, ' ');
console.log(foo);Run Code Online (Sandbox Code Playgroud)
#disp {
white-space: pre;
font-family: monospace
}Run Code Online (Sandbox Code Playgroud)
<div id="disp"></div>Run Code Online (Sandbox Code Playgroud)
tri*_*cot 213
首先,扩展被认为是不好的做法Object.prototype.相反,提供功能的实用功能上Object,就像目前已经有Object.keys,Object.assign,Object.is,...等等.
我在这提供了几个解决方案
reduce和Object.keysObject.assignmap和传播语法而不是reduceObject.entries和Object.fromEntriesreduce和Object.keys使用reduce和Object.keys实现所需的过滤器(使用ES6 箭头语法):
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);Run Code Online (Sandbox Code Playgroud)
注意,在上面的代码中predicate必须是一个包含条件(与OP使用的排除条件相反),因此它符合Array.prototype.filter工作原理.
Object.assign在上面的解决方案中,在部件中使用逗号运算符reduce来返回变异res对象.这当然可以写成两个语句而不是一个表达式,但后者更简洁.要在没有逗号运算符的情况下执行此操作,您可以使用Object.assign,它会返回变异对象:
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => Object.assign(res, { [key]: obj[key] }), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);Run Code Online (Sandbox Code Playgroud)
map和传播语法而不是reduce这里我们将Object.assign调用移出循环,因此它只进行一次,并将各个键作为单独的参数传递(使用扩展语法):
Object.filter = (obj, predicate) =>
Object.assign(...Object.keys(obj)
.filter( key => predicate(obj[key]) )
.map( key => ({ [key]: obj[key] }) ) );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);Run Code Online (Sandbox Code Playgroud)
Object.entries和Object.fromEntries当解决方案将对象转换为中间数组然后将其转换回普通对象时,使用Object.entries(ES2017)并使用相反方法(即从关键数组创建对象)将非常有用/值对).在撰写本文时,Object.fromEntries提案已进入第3阶段,Firefox已实施该提案.否则可以使用填充物.
它导致了这两种"单线"方法Object(包括polyfill):
Object.filter = (obj, predicate) =>
Object.fromEntries(Object.entries(obj).filter(predicate));
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, ([name, score]) => score > 1);
console.log(filtered);Run Code Online (Sandbox Code Playgroud)
谓词函数在这里获得一个键/值对作为参数,这有点不同,但在谓词函数的逻辑中允许更多的可能性.
use*_*716 167
永远不要延伸Object.prototype.
你的代码会发生可怕的事情.事情会破裂.您正在扩展所有对象类型,包括对象文字.
以下是您可以尝试的简单示例:
// Extend Object.prototype
Object.prototype.extended = "I'm everywhere!";
// See the result
alert( {}.extended ); // "I'm everywhere!"
alert( [].extended ); // "I'm everywhere!"
alert( new Date().extended ); // "I'm everywhere!"
alert( 3..extended ); // "I'm everywhere!"
alert( true.extended ); // "I'm everywhere!"
alert( "here?".extended ); // "I'm everywhere!"
Run Code Online (Sandbox Code Playgroud)
而是创建一个传递对象的函数.
Object.filter = function( obj, predicate) {
var result = {}, key;
// ---------------^---- as noted by @CMS,
// always declare variables with the "var" keyword
for (key in obj) {
if (obj.hasOwnProperty(key) && !predicate(obj[key])) {
result[key] = obj[key];
}
}
return result;
};
Run Code Online (Sandbox Code Playgroud)
Qui*_*inn 88
let romNumbers={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
Run Code Online (Sandbox Code Playgroud)
您可以romNumbers按键过滤对象:
const filteredByKey = Object.fromEntries(
Object.entries(romNumbers).filter(([key, value]) => key === 'I') )
// filteredByKey = {I: 1}
Run Code Online (Sandbox Code Playgroud)
或romNumbers按值过滤对象:
const filteredByValue = Object.fromEntries(
Object.entries(romNumbers).filter(([key, value]) => value === 5) )
// filteredByValue = {V: 5}
Run Code Online (Sandbox Code Playgroud)
Bog*_*n D 19
如果你愿意使用下划线或lodash,你可以使用pick(或相反omit).
下划线文档中的示例:
_.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age');
// {name: 'moe', age: 50}
Run Code Online (Sandbox Code Playgroud)
或者使用回调(对于lodash,使用pickBy):
_.pick({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) {
return _.isNumber(value);
});
// {age: 50}
Run Code Online (Sandbox Code Playgroud)
普通 ES6:
var foo = {
bar: "Yes"
};
const res = Object.keys(foo).filter(i => foo[i] === 'Yes')
console.log(res)
// ["bar"]
Run Code Online (Sandbox Code Playgroud)
正如patrick所说的,这是一个坏主意,因为它几乎肯定会破坏您可能希望使用的任何第三方代码。
如果扩展Object.prototype,所有类似jquery或prototype的库都将中断,原因是对象上的惰性迭代(不带hasOwnProperty检查)将中断,因为您添加的功能将成为迭代的一部分。
我创建了一个Object.filter()不仅按函数过滤,而且还接受要包含的键数组。可选的第三个参数将允许您反转过滤器。
var foo = {
x: 1,
y: 0,
z: -1,
a: 'Hello',
b: 'World'
}
Run Code Online (Sandbox Code Playgroud)
Object.filter(foo, ['z', 'a', 'b'], true);
Run Code Online (Sandbox Code Playgroud)
Object.filter(foo, function (key, value) {
return Ext.isString(value);
});
Run Code Online (Sandbox Code Playgroud)
免责声明:为了简洁起见,我选择使用 Ext JS 核心。认为没有必要为对象类型编写类型检查器,因为它不是问题的一部分。
var foo = {
x: 1,
y: 0,
z: -1,
a: 'Hello',
b: 'World'
}
Run Code Online (Sandbox Code Playgroud)
Object.filter(foo, ['z', 'a', 'b'], true);
Run Code Online (Sandbox Code Playgroud)
Object.filter(foo, function (key, value) {
return Ext.isString(value);
});
Run Code Online (Sandbox Code Playgroud)
给定的
object = {firstname: 'abd', lastname:'tm', age:16, school:'insat'};
keys = ['firstname', 'age'];
Run Code Online (Sandbox Code Playgroud)
然后 :
keys.reduce((result, key) => ({ ...result, [key]: object[key] }), {});
// {firstname:'abd', age: 16}
Run Code Online (Sandbox Code Playgroud)
object = {firstname: 'abd', lastname:'tm', age:16, school:'insat'};
keys = ['firstname', 'age'];
Run Code Online (Sandbox Code Playgroud)
怎么样:
function filterObj(keys, obj) {
const newObj = {};
for (let key in obj) {
if (keys.includes(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
Run Code Online (Sandbox Code Playgroud)
或者...
function filterObj(keys, obj) {
const newObj = {};
Object.keys(obj).forEach(key => {
if (keys.includes(key)) {
newObj[key] = obj[key];
}
});
return newObj;
}
Run Code Online (Sandbox Code Playgroud)
ES6方法...
假设您在下面有这个对象:
const developers = {
1: {
id: 1,
name: "Brendan",
family: "Eich"
},
2: {
id: 2,
name: "John",
family: "Resig"
},
3: {
id: 3,
name: "Alireza",
family: "Dezfoolian"
}
};
Run Code Online (Sandbox Code Playgroud)
创建一个函数:
const filterObject = (obj, filter, filterValue) =>
Object.keys(obj).reduce((acc, val) =>
(obj[val][filter] === filterValue ? acc : {
...acc,
[val]: obj[val]
}
), {});
Run Code Online (Sandbox Code Playgroud)
并称之为:
filterObject(developers, "name", "Alireza");
Run Code Online (Sandbox Code Playgroud)
并返回:
{
1: {
id: 1,
name: "Brendan",
family: "Eich"
},
2: {
id: 2,
name: "John",
family: "Resig"
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
var foo = {
bar: "Yes",
pipe: "No"
};
const ret = Object.entries(foo).filter(([key, value])=> value === 'Yes');
Run Code Online (Sandbox Code Playgroud)
https://masteringjs.io/tutorials/fundamentals/filter-object
| 归档时间: |
|
| 查看次数: |
270387 次 |
| 最近记录: |