![](/img/trans.png)
[英]How to filter and array and return new array of objects with indexed values?
[英]How do I `.filter()` an array/object and return a new array with the original keys and not as an indexed array/object as filter return?
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()
)。 真正的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; }
進行此類對象轉換的“正式”建議方法是使用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編寫“由內而外”的循環。
您可以獲取條目,過濾並構建新對象。
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; }
我會使用一個可迭代的生成器函數:
// 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));
這樣的算法
以下工作也很好:
var newObj = Object.entries(obj).filter(value => {return value[1].isActive ===0});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.