Results 1 to 4 of 4

Thread: Cloning Objects: Merging and Matching of objects

  1. #1

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Cloning Objects: Merging and Matching of objects

    Creating a new object that merges or copies other objects can create "referential" links that can burn you later on. You can easily have two objects with members that actually refer to the same address in memory. Changing one will change the other! This can cause major bugs if you are not expecting this!

    I use these functions mostly when dealing with AJAX calls and "call back" functions that fire when web responses come through. I also use them when "cloning" objects to make "new" objects (ones that might be "saving" filter settings that users can maintain and copy and what not).

    Function #1: mergeObjects()

    This function will merge two objects. If the "property" already exists it WILL NOT be touched. Any new properties in objFiller will be created in objMaster.

    This function copies the "value" of the element, so it should only be used for objects that have "value" type properties only.

    If you are merging objects that have properties that are arrays or objects themselves, use the next function (mergeObjectsDeep)

    Code:
    function mergeObjects(objMaster, objFiller) {
        for (var propertyName in objFiller) {
            if (typeof objMaster[propertyName] == "undefined") {
                objMaster[propertyName] = objFiller[propertyName];
            }
        }
    }

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  2. #2

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Cloning Objects: Merging and Matching of objects

    Function #2: mergeObjectsDeep()

    This function goes deeper - seeing "what" is being merged.

    If the property is an "array" it gets copied with .slice(0) so that a "new" array gets created in memory.

    If the property is an "object" then the mergeObjectsDeep() function is called recursively to move that element.

    Otherwise the value is copied.

    [edit] Only properties that do not already exist are copied. This is the same logic in mergeObjects() [/edit]

    Code:
    function mergeObjectsDeep(objMaster, objFiller) {
        for (var propertyName in objFiller) {
            if (typeof objMaster[propertyName] == "undefined") {
                if (Object.prototype.toString.call(objFiller[propertyName]) == "[object Array]") {
                    objMaster[propertyName] = objFiller[propertyName].slice(0);
                } else if (Object.prototype.toString.call(objFiller[propertyName]) == "[object Object]") {
                    objMaster[propertyName] = {};
                    mergeObjectsDeep(objMaster[propertyName], objFiller[propertyName]);
                } else {
                    objMaster[propertyName] = objFiller[propertyName];
                }
            }
        }
    }
    Function #3: mergeObjectsShallow()

    This function differs from mergeObjectsDeep in that it will only "create" an empty array or object if the property being copied is an array or object.

    Code:
    function mergeObjectsShallow(objMaster, objFiller) {
        for (var propertyName in objFiller) {
            if (typeof objMaster[propertyName] == "undefined") {
                if (Object.prototype.toString.call(objFiller[propertyName]) == "[object Array]") {
                    objMaster[propertyName] = [];
                } else if (Object.prototype.toString.call(objFiller[propertyName]) == "[object Object]") {
                    objMaster[propertyName] = {};
                } else {
                    objMaster[propertyName] = objFiller[propertyName];
                }
            }
        }
    }
    Function #4: mergeObjectsArray()

    This function specifically moves an "array" of "objects". Pushing a new empty object onto the array and then using mergeObjectsDeep to clone the element in that array slot.

    Code:
    function mergeObjectsArray(objMaster, objFiller) {
        for (var i = 0; i < objFiller.length; i++) {
            objMaster.push({});
            mergeObjectsDeep(objMaster[objMaster.length - 1], objFiller[i]);
        }
    }
    Last edited by szlamany; Aug 12th, 2021 at 05:39 AM.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  3. #3

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Cloning Objects: Merging and Matching of objects

    Function #5: matchObjects()

    Here is a function to see if two objects match. This is a simple function and should only be used on objects that contain just value properties (string, numeric, boolean).

    Code:
    function matchObjects(objMaster, objCheck) {
        var blnMatch = true;
        for (var propertyName in objCheck) {
            if (typeof objMaster[propertyName] == "undefined") {
                blnMatch = false;
                break;
            }
            if (!(objMaster[propertyName] == objCheck[propertyName])) {
                blnMatch = false;
                break;
            }
        }
        if (blnMatch) {
            for (var propertyName in objMaster) {
                if (typeof objCheck[propertyName] == "undefined") {
                    blnMatch = false;
                    break;
                }
                if (!(objCheck[propertyName] == objMaster[propertyName])) {
                    blnMatch = false;
                    break;
                }
            }
        }
        return blnMatch;
    }
    Last edited by szlamany; Aug 11th, 2021 at 04:41 PM.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  4. #4

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Cloning Objects: Merging and Matching of objects

    Example of use: mergeObjects()

    Both the objWebParam and options "object" contain an .objReturn property - which is an object.

    The .objReturn "object" contains just value properties (string, numeric, boolean). It does NOT contain properties that are array or objects themselves.

    Any "property" found in options.objReturn that does not already exist in objWebParam.objReturn will be created with that value copied.

    Code:
    mergeObjects(objWebParam.objReturn, options.objReturn);

    Example of use: matchObjects()

    Comparing two .objReturn objects. These objects contain just value properties (string, numeric, boolean) allowing this simple function to work.

    Code:
    blnMatchSproc = matchObjects(gaSprocs[i].what.options.objReturn, objOptions.objReturn);

    Example of use: mergeObjectsDeep(), mergeObjectsShallow() and mergeObjectsArray()

    This example is cloning a complex array element into a new slot in that same array. This is an array of objects.

    I am retaining the length, pushing a new object on, and then taking the [i] slot of the array and then cloning it's many members.

    A more intimate knowledge of the property types of the cloned object are needed so you can navigatee the many ways to move properties (you will notice I use just .slice() in places where a simple array is being moved or intentionally leaving it off to "force" a connection to the original array).

    Code:
    gmOffset = g_objGMaker.length;
    g_objGMaker.push({ status: "clone", clone: i, gm: gmOffset, gname: sName, filterTab: -1, gmProperties: {}, parentInfo: {}, gmSource: {} });
    g_objGMaker[gmOffset].gmSource.sourceOrig = g_objGMaker[i].gmSource.sourceOrig;
    g_objGMaker[gmOffset].gmSource.sourceOutput = g_objGMaker[i].gmSource.sourceOutput.slice(0);
    g_objGMaker[gmOffset].gmSource.sourceOutput.gm = gmOffset;
    mergeObjectsDeep(g_objGMaker[gmOffset].parentInfo, g_objGMaker[i].parentInfo);
    g_objGMaker[gmOffset].parentInfo.original = false;
    mergeObjectsShallow(g_objGMaker[gmOffset].gmProperties, g_objGMaker[i].gmProperties);
    mergeObjectsShallow(g_objGMaker[gmOffset].gmProperties.settingsObj, g_objGMaker[i].gmProperties.settingsObj);
    mergeObjectsShallow(g_objGMaker[gmOffset].gmProperties.curGraph, g_objGMaker[i].gmProperties.curGraph);
    for (var j = 0; j < g_objGMaker[i].gmProperties.arrFilters.length; j++) {
        g_objGMaker[gmOffset].gmProperties.arrFilters.push({});
        mergeObjectsShallow(g_objGMaker[gmOffset].gmProperties.arrFilters[g_objGMaker[gmOffset].gmProperties.arrFilters.length - 1], g_objGMaker[i].gmProperties.arrFilters[j]);
        g_objGMaker[gmOffset].gmProperties.arrFilters[g_objGMaker[gmOffset].gmProperties.arrFilters.length - 1].alphaCountList = g_objGMaker[i].gmProperties.arrFilters[j].alphaCountList.slice(0);
        mergeObjects(g_objGMaker[gmOffset].gmProperties.arrFilters[g_objGMaker[gmOffset].gmProperties.arrFilters.length - 1].alphaCountUsage, g_objGMaker[i].gmProperties.arrFilters[j].alphaCountUsage);
        g_objGMaker[gmOffset].gmProperties.arrFilters[g_objGMaker[gmOffset].gmProperties.arrFilters.length - 1].dataList = g_objGMaker[i].gmProperties.arrFilters[j].dataList.slice(0);
        mergeObjects(g_objGMaker[gmOffset].gmProperties.arrFilters[g_objGMaker[gmOffset].gmProperties.arrFilters.length - 1].dataUsage, g_objGMaker[i].gmProperties.arrFilters[j].dataUsage);
        mergeObjectsArray(g_objGMaker[gmOffset].gmProperties.arrFilters[g_objGMaker[gmOffset].gmProperties.arrFilters.length - 1].filter, g_objGMaker[i].gmProperties.arrFilters[j].filter);
    
    }
    if (g_objGMaker[gmOffset].gmProperties.settingsObj.colsum) {
        mergeObjectsArray(g_objGMaker[gmOffset].gmProperties.settingsObj.colsum, g_objGMaker[i].gmProperties.settingsObj.colsum);
    }
    if (g_objGMaker[gmOffset].gmProperties.settingsObj.selectedcols) {
        mergeObjectsArray(g_objGMaker[gmOffset].gmProperties.settingsObj.selectedcols, g_objGMaker[i].gmProperties.settingsObj.selectedcols);
    }
    if (g_objGMaker[gmOffset].gmProperties.settingsObj.arrcontrol) {
        g_objGMaker[gmOffset].gmProperties.settingsObj.arrcontrol = g_objGMaker[i].gmProperties.settingsObj.arrcontrol.slice(0);
    }
    if (g_objGMaker[gmOffset].gmProperties.settingsObj.columns) {
        g_objGMaker[gmOffset].gmProperties.settingsObj.columns = g_objGMaker[i].gmProperties.settingsObj.columns.slice(0);
    }
    if (g_objGMaker[gmOffset].gmProperties.messagepump) {
        g_objGMaker[gmOffset].gmProperties.messagepump = g_objGMaker[i].gmProperties.messagepump.slice(0);
    }
    Last edited by szlamany; Aug 12th, 2021 at 05:44 AM.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width