8000 just-merge is not working as expected · Issue #580 · angus-c/just · GitHub
[go: up one dir, main page]

Skip to content

just-merge is not working as expected #580

Open

Description

@R35007

Sample Input

const obj1 = {
      "appName": "React",
      "tags": ["react", 'mfe'],
      "fields": {
        "appName": {"type": "checkbox"},
        "template": {"type": "textbox","options": [{"label": "opt1"}, {}, {"label": "opt3","value": "value3"}, {"label": "opt4","value": "value4"},{"label": "opt5","value": "value5"}]},
        "projectName": {"type": "textbox"}
      }
    }

const obj2 = {
      "appName": "React",
      "tags": ["frontend"],
      "fields": {
        "appName": {"type": "checkbox","value": true,"label": "Confirm"},
        "template": {"type": "radio","options": [{"value": "value1"},{"label": "opt2","value": "value2"}, {}, {"label": "opt4","value": "value4"}]},
        "skipInstall": {"type": "checkbox","label": "Should Skip Install ?"}
      }
    }

Expected Output

{
  "appName": "React",
  "tags": ["react", "frontend", "mfe"],
  "fields": {
    "appName": { "type": "checkbox", "value": true, "label": "Confirm" },
    "template": {
      "type": "radio",
      "options": [
        { "label": "opt1", "value": "value1" },
        { "label": "opt2", "value": "value2" },
        { "label": "opt3", "value": "value3" },
        { "label": "opt4", "value": "value4" },
        { "label": "opt5", "value": "value5" }
      ]
    },
    "projectName": { "type": "textbox" },
    "skipInstall": { "type": "checkbox", "label": "Should Skip Install ?" }
  }
}

But What I get is

{
  "appName": "React",
  "tags": ["frontend"],
  "fields": {
    "appName": { "type": "checkbox", "value": true, "label": "Confirm" },
    "template": {
      "type": "radio",
      "options": [
            { "value": "value1" }, 
            { "label": "opt2", "value": "value2" }, 
            {}, 
            { "label": "opt4", "value": "value4" }
       ]
    },
    "skipInstall": { "type": "checkbox", "label": "Should Skip Install ?" }
  }
}

Activity

  1. uncenter commented on Jul 21, 2024

    @uncenter

    I believe you want to be using just-extend, not just-merge. Try extend(true, obj1, obj2).

  2. R35007 commented on Jul 21, 2024

    @R35007
    Author

    I believe you want to be using just-extend, not just-merge. Try extend(true, obj1, obj2).

    Tried that as well. still not getting the expected result

  3. uncenter commented on Jul 21, 2024

    @uncenter

    What is the difference between expected and what you are getting exactly?

  4. R35007 commented on Jul 21, 2024

    @R35007
    Author
    {
      "appName": "React",
      "tags": ["frontend", "mfe"],
      "fields": {
        "appName": { "type": "checkbox", "value": true, "label": "Confirm" },
        "template": {
          "type": "radio",
          "options": [
            { "label": "opt1", "value": "value1" },
            { "label": "opt2", "value": "value2" },
            { "label": "opt3", "value": "value3" },
            { "label": "opt4", "value": "value4" },
            { "label": "opt5", "value": "value5" }
          ]
        },
        "projectName": { "type": "textbox" },
        "skipInstall": { "type": "checkbox", "label": "Should Skip Install ?" }
      }
    }

    Have already share u what I get and what is expected.
    the arrays are not merging. its just replacing it on index.

  5. R35007 commented on Jul 21, 2024

    @R35007
    Author

    This is what I get

    {
      "appName": "React",
      "tags": ["frontend"],
      "fields": {
        "appName": { "type": "checkbox", "value": true, "label": "Confirm" },
        "template": {
          "type": "radio",
          "options": [{ "value": "value1" }, { "label": "opt2", "value": "value2" }, {}, { "label": "opt4", "value": "value4" }]
        },
        "skipInstall": { "type": "checkbox", "label": "Should Skip Install ?" }
      }
    }
    
  6. uncenter commented on Jul 21, 2024

    @uncenter

    Ah yeah I was also noticing that! But in your "expected" version you left a bit with that behavior so I thought that is what you wanted.

  7. R35007 commented on Jul 21, 2024

    @R35007
    Author
    const isArray = (val: unknown) => !!(val && typeof val === 'object' && Array.isArray(val));
    const isPlainObject = (val: unknown) => !!(val && typeof val === 'object' && !isArray(val));
    const isCollection = (val: unknown): val is Array<object> => !!(val && isArray(val) && val.length && val.every(isPlainObject));
    const isMatrix = (val: unknown): val is Array<unknown[]> => !!(val && isArray(val) && val.length && val.every(isArray));
    const isPrimitive = (val: unknown) => !!(val && typeof val !== 'object');
    const getValuesByKey = (args: object[], keyName: string) =>
      args
        .map((obj) =>
          Object.entries(obj)
            .filter(([key]) => key === keyName)
            .map(([, value]) => value)
        )
        .flat();
    const getValuesByIndex = (args: Array<unknown[]>, index: number) => args.map((arr) => arr[index]).flat();
    
    function mergeDeep(...args: unknown[]): object | unknown[] {
      if (isCollection(args)) {
        const allKeys = args.map((obj) => Object.entries(obj).map(([key]) => key)).flat();
        const entries = allKeys.map((key) => {
          const values = getValuesByKey(args as object[], key);
          return values.every(isPrimitive) ? [key, values[values.length - 1]] : [key, mergeDeep(...values)];
        });
        return Object.fromEntries(entries);
      }
    
      if (isMatrix(args)) {
        const maxArrayLength = args.reduce((acc, item) => (acc >= item.length ? acc : item.length), 0);
        return [...Array(maxArrayLength).keys()].map((index) => mergeDeep(...getValuesByIndex(args, index))).flat();
      }
    
      return [...new Set(args)].filter(Boolean);
    }
    
    export default mergeDeep;

    This is what I have comeup with. Feel free to use it for merge or expand

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0