这个问题已在SO中多次提出,但它们都是指一组对象。
在我的情况下,我想过滤对象的对象。
说我有这个对象:
"Users": {
"w14FKo72BieZwbxwUouTpN7UQm02": {
"name": "Naseebullah Ahmadi",
"userType": "Patient",
"writePermission": false
},
"SXMrXfBvexQUXfnVg5WWVwsKjpD2": {
"name": "Levi Yeager",
"userType": "Patient",
"writePermission": false
},
"VoxHFgUEIwRFWg7JTKNXSSoFoMV2": {
"name": "Ernest Kamavuako",
"userType": "Doctor",
"writePermission": true
},
"hFoWuyxv6Vbt8sEKA87T0720tXV2": {
"name": "Karla Stanlee",
"userType": "Doctor",
"writePermission": true
}
}
我想过滤这个,以便我可以得到以下内容:
"UsersCustom": {
"w14FKo72BieZwbxwUouTpN7UQm02": {
"name": "Naseebullah Ahmadi",
"userType": "Patient",
"writePermission": false
},
"SXMrXfBvexQUXfnVg5WWVwsKjpD2": {
"name": "Levi Yeager",
"userType": "Patient",
"writePermission": false
}
}
请注意,此对象“用户”实际上是巨大的(超过1000个条目),并且每个用户拥有的属性多于“name”,“userType”和“writePermission”。
我需要过滤用户对象的原因是我可以获得仅(患者)的用户并获取该患者的ID以在另一个对象中查找并最终将它们合并在一个对象中。
// user is the object as seen above
let Patients = users ? (
// I loop through them
Object.keys(users).map((uid, i) => {
// get individual patient
const patient = users[uid];
// check their userType
if (patient.userType === "Patient") {
let customPatient = {
uid: uid,
name: patient.name,
profession: patient.profession,
history: null,
ecg: null,
heartSound: null
};
this._healthRef(uid).then(health => {
customPatient.history = health;
return this._heartSoundRef(uid).then(HS => HS);
}).then(HS => {
customPatient.heartSound = HS;
return this._ecgRef(uid).then(a => a);
}).then(ecg => {
customPatient.ecg = ecg;
}).then(() => {
cusomPatients.push(customPatient);
})
}
})
)
我的上述解决方案尽管部分完成,仍然没有效率和错误。因为我需要每个患者的Id进行其他查询
目前,大多数解决方案都提供了通过条目的循环,这意味着它将在最坏的情况下运行O(n)。是否有可能比O(n)更快地解决?
答案 0 :(得分:2)
我的猜测是,在解析过程中过滤可能是最有效的(避免测量/比较它):
j = '{"w14FKo72BieZwbxwUouTpN7UQm02":{"name":"Naseebullah Ahmadi","userType":"Patient","writePermission":false},"SXMrXfBvexQUXfnVg5WWVwsKjpD2":{"name":"Levi Yeager","userType":"Patient","writePermission":false},"VoxHFgUEIwRFWg7JTKNXSSoFoMV2":{"name":"Ernest Kamavuako","userType":"Doctor","writePermission":true},"hFoWuyxv6Vbt8sEKA87T0720tXV2":{"name":"Karla Stanlee","userType":"Doctor","writePermission":true}}'
o = JSON.parse(j, (k, v) => !v.userType || v.userType === 'Patient' ? v : void 0)
console.log(o)

缓存过滤后的对象可以更有效地减少网络流量。
答案 1 :(得分:1)
使用reduce
方法可以获取对象
var data = {
"w14FKo72BieZwbxwUouTpN7UQm02": {
"name": "Naseebullah Ahmadi",
"userType": "Patient",
"writePermission": false
},
"SXMrXfBvexQUXfnVg5WWVwsKjpD2": {
"name": "Levi Yeager",
"userType": "Patient",
"writePermission": false
},
"VoxHFgUEIwRFWg7JTKNXSSoFoMV2": {
"name": "Ernest Kamavuako",
"userType": "Doctor",
"writePermission": true
},
"hFoWuyxv6Vbt8sEKA87T0720tXV2": {
"name": "Karla Stanlee",
"userType": "Doctor",
"writePermission": true
}
};
var results = Object.keys(data).reduce(function(acc, val) {
if(data[val].userType === 'Patient') acc[val] = data[val];
return acc;
}, {});
console.log(results);
答案 2 :(得分:0)
您可以使用for-in
或Object.keys
或(在现代JavaScript引擎上)Object.entries
解决此问题。
for-in
提供了迭代对象的可枚举属性的方法;然后,您可以使用这些属性名称来查找值:
var result = {};
for (var key in users) {
var entry = users[key];
if (entry.userType === "Patient") {
result[key] = entry;
}
}
直播示例:
var users = {
"w14FKo72BieZwbxwUouTpN7UQm02": {
"name": "Naseebullah Ahmadi",
"userType": "Patient",
"writePermission": false
},
"SXMrXfBvexQUXfnVg5WWVwsKjpD2": {
"name": "Levi Yeager",
"userType": "Patient",
"writePermission": false
},
"VoxHFgUEIwRFWg7JTKNXSSoFoMV2": {
"name": "Ernest Kamavuako",
"userType": "Doctor",
"writePermission": true
},
"hFoWuyxv6Vbt8sEKA87T0720tXV2": {
"name": "Karla Stanlee",
"userType": "Doctor",
"writePermission": true
}
};
var result = {};
for (var key in users) {
var entry = users[key];
if (entry.userType === "Patient") {
result[key] = entry;
}
}
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
Object.keys
为您提供了对象的拥有可枚举属性的数组,因此:
var result = {};
Object.keys(users).forEach(function(key) {
var entry = users[key];
if (entry.userType === "Patient") {
result[key] = entry;
}
});
直播示例:
var users = {
"w14FKo72BieZwbxwUouTpN7UQm02": {
"name": "Naseebullah Ahmadi",
"userType": "Patient",
"writePermission": false
},
"SXMrXfBvexQUXfnVg5WWVwsKjpD2": {
"name": "Levi Yeager",
"userType": "Patient",
"writePermission": false
},
"VoxHFgUEIwRFWg7JTKNXSSoFoMV2": {
"name": "Ernest Kamavuako",
"userType": "Doctor",
"writePermission": true
},
"hFoWuyxv6Vbt8sEKA87T0720tXV2": {
"name": "Karla Stanlee",
"userType": "Doctor",
"writePermission": true
}
};
var result = {};
Object.keys(users).forEach(function(key) {
var entry = users[key];
if (entry.userType === "Patient") {
result[key] = entry;
}
});
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
Object.entries
提供了一个iterable,它包含每个拥有的可枚举属性的名称和值。这是新的。例如(在ES2015 +语法中,ES2017中添加了Object.entries
但可以进行多层填充):
const result = {};
for (const [key, value] of Object.entries(users)) {
if (value.userType === "Patient") {
result[key] = value;
}
}
直播示例:
const users = {
"w14FKo72BieZwbxwUouTpN7UQm02": {
"name": "Naseebullah Ahmadi",
"userType": "Patient",
"writePermission": false
},
"SXMrXfBvexQUXfnVg5WWVwsKjpD2": {
"name": "Levi Yeager",
"userType": "Patient",
"writePermission": false
},
"VoxHFgUEIwRFWg7JTKNXSSoFoMV2": {
"name": "Ernest Kamavuako",
"userType": "Doctor",
"writePermission": true
},
"hFoWuyxv6Vbt8sEKA87T0720tXV2": {
"name": "Karla Stanlee",
"userType": "Doctor",
"writePermission": true
}
};
const result = {};
for (const [key, value] of Object.entries(users)) {
if (value.userType === "Patient") {
result[key] = value;
}
}
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
答案 3 :(得分:0)
您可以在对象键上使用reduce()
方法并从中构建新对象。
const obj = {"Users":{"w14FKo72BieZwbxwUouTpN7UQm02":{"name":"Naseebullah Ahmadi","userType":"Patient","writePermission":false},"SXMrXfBvexQUXfnVg5WWVwsKjpD2":{"name":"Levi Yeager","userType":"Patient","writePermission":false},"VoxHFgUEIwRFWg7JTKNXSSoFoMV2":{"name":"Ernest Kamavuako","userType":"Doctor","writePermission":true},"hFoWuyxv6Vbt8sEKA87T0720tXV2":{"name":"Karla Stanlee","userType":"Doctor","writePermission":true}}}
const newObj = {
'UserCustom': Object.keys(obj.Users).reduce((r, k) => {
if(obj.Users[k].userType == 'Patient') r[k] = Object.assign({}, obj.Users[k])
return r;
}, {})
}
console.log(newObj)

答案 4 :(得分:0)
使用for...in
迭代对象并检查其他用户是否有耐心。
var users = {
"Users": {
"w14FKo72BieZwbxwUouTpN7UQm02": {
"name": "Naseebullah Ahmadi",
"userType": "Patient",
"writePermission": false
},
"SXMrXfBvexQUXfnVg5WWVwsKjpD2": {
"name": "Levi Yeager",
"userType": "Patient",
"writePermission": false
},
"VoxHFgUEIwRFWg7JTKNXSSoFoMV2": {
"name": "Ernest Kamavuako",
"userType": "Doctor",
"writePermission": true
},
"hFoWuyxv6Vbt8sEKA87T0720tXV2": {
"name": "Karla Stanlee",
"userType": "Doctor",
"writePermission": true
}
}
};
for(let user in users.Users){
if(users.Users.hasOwnProperty(user) && users.Users[user].userType!=="Patient")
delete users.Users[user];
}
console.log(users);

这将修改对象,如果要保留它,则只需执行原始对象的deep copy。