Вот функция (Python 3.1), чтобы проверить, является ли результат функции слияния ОК. Он проверяет:
.
from itertools import chain
def check(lsts, result):
lsts = [set(s) for s in lsts]
all_items = set(chain(*lsts))
all_result_items = set(chain(*result))
num_result_items = sum(len(s) for s in result)
if num_result_items != len(all_result_items):
print("Error: result sets overlap!")
print(num_result_items, len(all_result_items))
print(sorted(map(len, result)), sorted(map(len, lsts)))
if all_items != all_result_items:
print("Error: result doesn't match input lists!")
if not all(any(set(s).issubset(t) for t in result) for s in lst):
print("Error: not all input lists are contained in a result set!")
seen = set()
todo = list(filter(bool, lsts))
done = False
while not done:
deletes = []
for i, s in enumerate(todo): # intersection with seen, or with unseen result set, is OK
if not s.isdisjoint(seen) or any(t.isdisjoint(seen) for t in result if not s.isdisjoint(t)):
seen.update(s)
deletes.append(i)
for i in reversed(deletes):
del todo[i]
done = not deletes
if todo:
print("Error: A result set should be split into two or more parts!")
print(todo)
Самый простой способ понять, почему лучше использовать «более плоскую» структуру, - это посмотреть, как вы ее защищаете и как реализовать функциональность.
Ваша первая структура:
users: {
uidOfJacob: {
stackId: 884522,
ssn: "999-99-9999",
profile: {
displayName: "Jacob Philips"
}
},
uidOfPuf: {
stackId: 209103,
ssn: "999-99-9999",
profile: {
displayName: "Frank van Puffelen"
}
}
}
Вы обеспечили бы его с помощью:
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
"profile": {
".read": true
}
}
}
}
}
. Одна из основных причин наличия публичной информации - показать список этой информации. В JavaScript:
ref.child('users').child(???).child('profile').on('child_added'...
Это не сработает, потому что мы помещаем ???
. Операции Firebase должны иметь возможность читать весь список из одного места, и пользователю необходимо иметь разрешение на чтение во всем этом местоположении (а не только на отдельные дочерние узлы).
Если мы структурируем данные для отделите общедоступную информацию от частной информации, мы получим:
users: {
uidOfJacob: {
stackId: 884522,
ssn: "999-99-9999",
profile: {
displayName: "Jacob Philips"
}
},
uidOfPuf: {
stackId: 209103,
ssn: "999-99-9999",
profile: {
displayName: "Frank van Puffelen"
}
}
},
"profile": {
uidOfJacob: {
displayName: "Jacob Philips"
},
uidOfPuf: {
displayName: "Frank van Puffelen"
}
}
Вы обеспечили бы ее с помощью:
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
},
"profiles": {
".read": true,
"$uid": {
".write": "auth.uid == $uid"
}
}
}
}
Не получать список профилей публичных пользователей, вы будете делать:
ref.child('profiles').on('child_added'...
Это будет работать, потому что у всех есть разрешение на чтение на profiles
.