如何有效地过滤对象的对象?

时间:2018-02-17 13:53:06

标签: javascript json object filter object-properties

这个问题已在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)更快地解决?

5 个答案:

答案 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-inObject.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