/** * 项目禁用原生 Set(小游戏运行时对部分 Set 用法不稳定)。 * 用 Map 表示成员集合;迭代时 yield key(与 Set 一致,而非 Map 的 [key, value])。 */ export type MembershipSet = Map; export type ReadonlyMembershipSet = ReadonlyMap; function bindMembershipIterator(set: Map): MembershipSet { (set as unknown as { [Symbol.iterator]: () => IterableIterator })[Symbol.iterator] = () => set.keys(); return set; } export function createMembershipSet(): MembershipSet { return bindMembershipIterator(new Map()); } export function membershipAdd(set: MembershipSet, key: K): MembershipSet { set.set(key, true); return set; } export function membershipHas(set: ReadonlyMembershipSet, key: K): boolean { return set.has(key); } export function membershipDelete(set: MembershipSet, key: K): boolean { return set.delete(key); } export function membershipClear(set: MembershipSet): void { set.clear(); } export function membershipFromArray(items: Iterable): MembershipSet { const set = createMembershipSet(); for (const item of items) { set.set(item, true); } return set; } /** * 将 Map 的 key 收成数组。 * 勿用 `[...map.keys()]` / `Array.from(map.keys())`:H5 构建可能编成 `concat(iterator)`,得到空对象。 */ export function mapKeysToArray(map: ReadonlyMap): K[] { const out: K[] = []; map.forEach((_v, k) => { out.push(k); }); return out; } /** * 将 Map 的 value 收成数组。 * 勿用 `[...map.values()]` / `Array.from(map.values())`。 */ export function mapValuesToArray(map: ReadonlyMap): V[] { const out: V[] = []; map.forEach((v) => { out.push(v); }); return out; } /** 成员集合转数组(forEach 收 key,避免展开 Map 迭代器) */ export function membershipToArray(set: ReadonlyMembershipSet): K[] { return mapKeysToArray(set); } export function membershipForEach(set: ReadonlyMembershipSet, fn: (key: K) => void): void { set.forEach((_v, key) => fn(key)); } /** 去重数组(替代 Array.from(new Set(...)) / [...new Set(...)]) */ export function membershipDedupeArray(items: Iterable): K[] { return membershipToArray(membershipFromArray(items)); }