Skip to content

Commit 19980d3

Browse files
authored
chore/SOF-6462: Implement application-model filter (#43)
* chore: add util function for merging terminal nodes * chore: check for plain object instead * test: basic functionality of mergeTerminalNodes * chore: add mergeTerminalNodes to index
1 parent e5a71be commit 19980d3

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

src/utils/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
convertKeysToCamelCaseForObject,
1515
flattenObject,
1616
getOneMatchFromObject,
17+
mergeTerminalNodes,
1718
renameKeysForObject,
1819
safeMakeObject,
1920
sortKeysDeepForObject,
@@ -71,4 +72,5 @@ export {
7172
replaceUnit,
7273
mapTree,
7374
getSchemaWithDependencies,
75+
mergeTerminalNodes,
7476
};

src/utils/object.js

+38
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,41 @@ export function sortKeysDeepForObject(obj) {
176176
}
177177
return obj;
178178
}
179+
180+
/**
181+
* Merge terminal node values of an object tree.
182+
* @param {Object} tree - Nested object
183+
* @param {Boolean} unique - Whether merged list should consist of unique items
184+
* @return {Array} - Merged list of values of terminal nodes.
185+
* @example
186+
* const tree = {
187+
* level1: {
188+
* level2a: {
189+
* level3a: {
190+
* key1: ['a', 'b', 'c'],
191+
* },
192+
* level3b: {
193+
* key2: ['d', 'e', 'f'],
194+
* },
195+
* },
196+
* level2b: {
197+
* level3c: {
198+
* key3: ['g', 'h', 'i'],
199+
* },
200+
* level3d: {
201+
* key4: ['j', 'k', 'l'],
202+
* },
203+
* },
204+
* },
205+
* };
206+
* mergeTerminalNodes(tree); // ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
207+
*/
208+
export function mergeTerminalNodes(tree, unique = false) {
209+
const terminalValues = lodash.values(tree).reduce((accumulator, value) => {
210+
if (lodash.isPlainObject(value)) {
211+
return accumulator.concat(mergeTerminalNodes(value));
212+
}
213+
return accumulator.concat(value);
214+
}, []);
215+
return unique ? [...new Set(terminalValues)] : terminalValues;
216+
}

tests/object.tests.js

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { expect } from "chai";
22

3-
import { flattenObject } from "../src/utils/object";
3+
import { flattenObject, mergeTerminalNodes } from "../src/utils/object";
44

55
describe("flattenObject", () => {
66
it("serializes simple object", () => {
@@ -46,3 +46,40 @@ describe("flattenObject", () => {
4646
}).to.throw();
4747
});
4848
});
49+
50+
describe("mergeTerminalNodes", () => {
51+
it("merges terminal nodes containing an array of strings", () => {
52+
const treeStrings = {
53+
level1: {
54+
level2a: {
55+
level3a: {
56+
key1: ["a", "b", "c"],
57+
},
58+
level3b: {
59+
key2: ["d", "e", "f"],
60+
},
61+
},
62+
},
63+
};
64+
const merged = mergeTerminalNodes(treeStrings);
65+
expect(merged).to.have.members(["a", "b", "c", "d", "e", "f"]);
66+
});
67+
68+
it("merges terminal nodes containing an array of objects", () => {
69+
const treeObjects = {
70+
level1: {
71+
level2a: {
72+
level3a: {
73+
key1: [{ path: "a" }, { path: "b" }, { path: "c" }],
74+
},
75+
level3b: {
76+
key2: [{ path: "d" }, { path: "e" }, { path: "f" }],
77+
},
78+
},
79+
},
80+
};
81+
const merged = mergeTerminalNodes(treeObjects);
82+
expect(merged).to.have.length(6);
83+
expect(merged.map((o) => o.path)).to.have.members(["a", "b", "c", "d", "e", "f"]);
84+
});
85+
});

0 commit comments

Comments
 (0)