skip to Main Content

I have an object of objects of a company’s hierarchy selection, for example:

{
  1:   { division: "division1" },
  2:   { division: "division2" },
  11:  { division: "division2", branch: "branch2" },
  41:  { division: "division2", branch: "branch2", department: "department2" },
  100: { division: "division2", branch: "branch2", department: "department10" },
  102: { division: "division2", branch: "branch3" },
  130: { division: "division17" },
  144: { division: "division17" , branch: "branch22" },
  200: { division: "division50" }
}

And I need to get the unique objects but most detailed ones. So the above example should result in:

{
  1:   { division: "division1" },
  41:  { division: "division2", branch: "branch2", department: "department2" },
  100: { division: "division2", branch: "branch2", department: "department10" },
  102: { division: "division2", branch: "branch3" },
  144: { division: "division17" , branch: "branch22" },
  200: { division: "division50" }
}

These are selections from 3 dropdowns, each selection holds the data of the entire hierarchy up to that item (The hierarchy is division > branch > department). So if a user selects division2 then branch2, it will add both { division: "division2" } and { division: "division2", branch: "branch2" } but I only need the most detailed one, { division: "division2", branch: "branch2" } in this case.

*Edit: It is not necessary to keep the original keys

How can I do that?

3

Answers


  1. I am assuming by most detailed you mean the object containing the most properties, hence being the most detailed object?

    In that case you could possible count the amount of keys in the object, and only grab the object with the most keys, hence grabbing the most detailed object.

    EDIT: If the objects will always have at least the division key value, you could execute these steps:

    1. First look for objects that share the same key value for division. If there are no matches, it’s unique and the most detailed already.
    2. Extract the object that has the most key/value pairs in the object. So { division: "val1", key2: "val2"} gets returned, and { division: "val1" } does not.

    You should end up with objects that have unique division values, and are the most detailed objects.

    Login or Signup to reply.
  2. let a = {
        1: { division: "division1" },
        2: { division: "division2" },
        11: { division: "division2", branch: "branch2" },
        41: { division: "division2", branch: "branch2", department: "department2" },
        100: { division: "division2", branch: "branch2", department: "department10" },
        102: { division: "division2", branch: "branch3" },
        130: { division: "division17" },
        144: { division: "division17", branch: "branch22" },
        200: { division: "division50" }
    }
    const aList = Object.values(a) 
    
    
    // 1. save all into Map by id
    const map = new Map();
    for (let value of aList) {
        const id = `${value.division} / ${value.branch} / ${value.department}`;
        map.set(id, value);
    }
    // 2. remove duplicates
    for (let value of aList) {
        const id3 = `${value.division} / ${value.branch} / ${value.department}`;
        if (map.get(id3) != value) map.delete(id3);
        const id2 = `${value.division} / ${value.branch} / ${undefined}`;
        if (map.get(id2) != value) map.delete(id2);
        const id1 = `${value.division} / ${undefined} / ${undefined}`;
        if (map.get(id1) != value) map.delete(id1);
    }
    const result = Array.from(map.values());
    console.log(result)
    
    Login or Signup to reply.
  3. You could build a tree with known values and filter the array by looking to values or check the length of the properties.

    const
        data = { 1: { division: "division1" }, 2: { division: "division2" }, 11: { division: "division2", branch: "branch2" }, 41: { division: "division2", branch: "branch2", department: "department2" }, 100: { division: "division2", branch: "branch2", department: "department10" }, 100: { division: "division2", branch: "branch3" }, 130: { division: "division17" }, 144: { division: "division17", branch: "branch22" }, 200: { division: "division50" } },
        keys = ['division', 'branch', 'department'],
        tree = Object.values(data).reduce((r, o) => {
            keys.reduce((q, k) => o[k] && (q[o[k]] ??= {}), r);
            return r;
        }, {}),
        result = Object
            .values(data)
            .filter(o => {
                let t = tree;
                return keys.every(k => {
                    if (o[k] in t) return t = t[o[k]];
                    return !Object.keys(t).length;
                });
            });
    
    console.log(result);
    console.log(tree);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    If you do not need the original objects, you could build the result set from the tree.

    const
        getObjects = (tree, [key, ...keys]) => {
            const entries = Object.entries(tree);
            return entries.length
                ? entries.flatMap(([k, t]) => getObjects(t, keys).map(o => ({ [key]: k, ...o })))
                : [{}];
        },
        data = { 1: { division: "division1" }, 2: { division: "division2" }, 11: { division: "division2", branch: "branch2" }, 41: { division: "division2", branch: "branch2", department: "department2" }, 100: { division: "division2", branch: "branch2", department: "department10" }, 100: { division: "division2", branch: "branch3" }, 130: { division: "division17" }, 144: { division: "division17", branch: "branch22" }, 200: { division: "division50" } },
        keys = ['division', 'branch', 'department'],
        tree = Object.values(data).reduce((r, o) => {
            keys.reduce((q, k) => o[k] && (q[o[k]] ??= {}), r);
            return r;
        }, {}),
        result = getObjects(tree, keys);
    
    console.log(result);
    console.log(tree);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search