0

这个问题在 SO 中已经提出过很多次了,但都是指一个对象数组

就我而言,我想过滤一个对象 objects

假设我有这个对象:

"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 个条目),每个用户的属性不仅仅是“名称”、“用户类型”和“写入权限”。

我需要过滤用户对象的原因是我可以获取只有(Patient)的用户并获取该 Patient 的 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) 更快地解决它?

4

5 回答 5

3

使用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);
于 2018-02-17T14:18:00.757 回答
1

我的猜测是解析期间的过滤可能是最有效的(没有测量/比较它):

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)

缓存过滤后的对象可以更有效地减少网络流量。

于 2018-02-17T14:11:06.987 回答
0

for-in您可以使用orObject.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提供了一个迭代,它由每个自己的可枚举属性的名称和值组成。它很新。例如(在 ES2015+ 语法中,Object.entries在 ES2017 中添加但可以填充):

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;
}

于 2018-02-17T14:00:59.770 回答
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)

于 2018-02-17T14:02:42.430 回答
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);

这将修改对象,如果您想保留它,那么只需对原始对象进行深层复制

于 2018-02-17T14:05:44.577 回答