Use asyncTreeFlatMap instead of asyncTreeMap

FlatMap is more powerful than map. More importantly, I only want to maintain one tree map function if I can help it.
This commit is contained in:
Jordan Eldredge 2019-07-20 17:04:54 -07:00
parent e2e88b4292
commit dd02f2ca7d
3 changed files with 1 additions and 49 deletions

View file

@ -55,7 +55,7 @@ async function getSkin() {
// const system = new System();
const images = {};
await Utils.asyncTreeMap(skinXml, async node => {
await Utils.asyncTreeFlatMap(skinXml, async node => {
// TODO: This is probalby only valid if in an `<elements>` node
switch (node.name) {
case "bitmap": {

View file

@ -96,19 +96,3 @@ export async function inlineIncludes(xml, zip) {
return includedFile.children;
});
}
// Transform an tree structure by mapping over each node breadth first
// Parents are mapped before their children
// Children are mapped in parallel
export async function asyncTreeMap(node, mapper) {
const mapped = await mapper(node);
if (mapped.children == null) {
return mapped;
}
const promises = mapped.children.map(child => {
return asyncTreeMap(child, mapper);
});
const children = await Promise.all(promises);
return { ...mapped, children };
}

View file

@ -25,38 +25,6 @@ describe("readXml", () => {
});
});
describe("asyncTreeMap", () => {
it("runs parents before children", async () => {
const callNodeNames = new Set();
const mapper = node => {
callNodeNames.add(node.name);
if (node.name === "root.2") {
const children = [{ name: "root.2.1" }];
return { ...node, children };
}
return node;
};
const structure = {
name: "root",
children: [{ name: "root.1" }, { name: "root.2" }, { name: "root.3" }],
};
const mappedStructure = await Utils.asyncTreeMap(structure, mapper);
expect(callNodeNames).toEqual(
new Set(["root", "root.1", "root.2", "root.2.1", "root.3"])
);
expect(mappedStructure).toEqual({
name: "root",
children: [
{ name: "root.1" },
{ name: "root.2", children: [{ name: "root.2.1" }] },
{ name: "root.3" },
],
});
});
});
describe("inlineIncludes", () => {
test("asyncTreeFlatMap", async () => {
const playerElements = {