var obj = {
111: {
user_id: 111,
user_name: "user111",
isActive: 0
},
112: {
user_id: 112,
user_name: "use112",
isActive: 1
},
113: {
user_id: 113,
user_name: "use113",
isActive: 0
},
...
}
我想过滤所有("isActive" === 0)
,但在返回newObj时,将键设置为相同(等于用户ID):
newObj = {
111: {
user_id: 111,
user_name: "user111",
isActive: 0
},
113: {
user_id: 113,
user_name: "use113",
isActive: 0
},
...
}
这就是我现在拥有的:
let newObj = Object.values(obj).filter( user => ( (obj.isActive === 0)));
返回索引键
.forEach()
)。 答案 0 :(得分:6)
真正的FP方式将是reduce
,且对象会重复散布:
const filtered = Object.values(obj).reduce((p, e) => (!e.isActive ? {...p, [e.user_id]: e} : p), {});
const obj = {
111: {
user_id: 111,
user_name: "user111",
isActive: 0
},
112: {
user_id: 112,
user_name: "use112",
isActive: 1
},
113: {
user_id: 113,
user_name: "use113",
isActive: 0
}
};
const filtered = Object.values(obj).reduce((p, e) => (!e.isActive ? {...p, [e.user_id]: e} : p), {});
console.log(filtered);
.as-console-wrapper {
max-height: 100% !important;
}
这会创建很多不必要的临时对象,但是通过不修改对象来遵守FP原则(我认为我对FP并不“深入”:)。
稍微修改一下规则,我们可能会修改单个对象而不是创建大量临时对象:
const filtered = Object.values(obj).reduce((newObj, e) => {
if (!e.isActive) {
newObj[e.user_id] = e;
}
return newObj;
}, {});
const obj = {
111: {
user_id: 111,
user_name: "user111",
isActive: 0
},
112: {
user_id: 112,
user_name: "use112",
isActive: 1
},
113: {
user_id: 113,
user_name: "use113",
isActive: 0
}
};
const filtered = Object.values(obj).reduce((newObj, e) => {
if (!e.isActive) {
newObj[e.user_id] = e;
}
return newObj;
}, {});
console.log(filtered);
.as-console-wrapper {
max-height: 100% !important;
}
(通过滥用逗号运算符,可以用较少的字符来写,但它的维护性较差,更难阅读。)
没有FP限制,我只使用循环:
const filtered = {};
for (const e of Object.values(obj)) {
if (!e.isActive) {
filtered[e.user_id] = e;
}
}
const obj = {
111: {
user_id: 111,
user_name: "user111",
isActive: 0
},
112: {
user_id: 112,
user_name: "use112",
isActive: 1
},
113: {
user_id: 113,
user_name: "use113",
isActive: 0
}
};
const filtered = {};
for (const e of Object.values(obj)) {
if (!e.isActive) {
filtered[e.user_id] = e;
}
}
console.log(filtered);
.as-console-wrapper {
max-height: 100% !important;
}
答案 1 :(得分:2)
建议的进行对象转换的“正式”方法是使用Object.entries
“线性化”对象,对键/值对执行映射/过滤,然后将它们与Object.fromEntries
放回原处。后者是新的,因此您需要一个polyfill。
示例:
// polyfill
Object.fromEntries = Object.fromEntries || function(pairs) {
let obj = {};
for (let [k, v] of pairs)
obj[k] = v;
return obj;
};
var myObj = {
111: {
user_id: 111,
user_name: "user111",
isActive: 0
},
112: {
user_id: 112,
user_name: "use112",
isActive: 1
},
113: {
user_id: 113,
user_name: "use113",
isActive: 0
},
};
result = Object.fromEntries(
Object.entries(myObj)
.filter(([k, v]) => v.isActive));
console.log(result)
自从您请求FP解决方案以来,这里是一种可能的概括:
let apply = (x, fn) => fn(x);
let pipe = (...fns) => x => fns.reduce(apply, x);
let transform = fn => pipe(Object.entries, fn, Object.fromEntries);
let filter = fn => a => a.filter(fn);
let filterObject = fn => transform(filter(fn));
let removeInactive = filterObject(([k, v]) => v.isActive);
console.log(removeInactive(myObj))
FP的目的是根据功能组成表达程序,而不是用reduce编写“由内而外”的循环。
答案 2 :(得分:1)
您可以获取条目,过滤并构建新对象。
var object = { 111: { user_id: 111, user_name: "user111", isActive: 0 }, 112: { user_id: 112, user_name: "use112", isActive: 1 }, 113: { user_id: 113, user_name: "use113", isActive: 0 } },
result = Object.assign(...Object
.entries(object)
.filter(({ 1: { isActive } }) => isActive === 0)
.map(([k, v]) => ({ [k]: v }))
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 3 :(得分:1)
我将使用带有可迭代功能的生成器函数:
// make object type iterable
function* objEntries(o) {
for (let k in o)
yield [k, o[k]];
}
// generator function that takes an iterable
const itFilter = p => function* (ix) {
for (const x of ix)
if (p(x))
yield x;
};
const obj = {
111: {
user_id: 111,
user_name: "user111",
isActive: 0
},
112: {
user_id: 112,
user_name: "use112",
isActive: 1
},
113: {
user_id: 113,
user_name: "use113",
isActive: 0
}
};
// exhaust the iterator with a strict evaluated fold
const itFoldStrict = f => acc => ix => {
let acc_ = acc;
for (const x of ix)
acc_ = f(acc_) (x);
return acc_;
};
const ix = itFilter(([k, o]) => o.isActive === 0)
(objEntries(obj));
// nothin has happened here due to lazy evaluation
// unleash the effect (of constructing the filtered object)
console.log(
itFoldStrict(acc => ([k, v]) => (acc[k] = v, acc))
({}) (ix));
这种算法
答案 4 :(得分:0)
以下内容也可以正常工作:
var newObj = Object.entries(obj).filter(value => {return value[1].isActive ===0});