goldis
10/21/2019 - 1:35 PM

setTempId

export default {
    setTempId,
    deleteTempId,
    deepClone,
};

function typeOf(entity) {
    const type = Object.prototype.toString
        .call(entity)
        .replace(/^\[object (.+)\]$/, '$1')
        .toLowerCase();
    if (type === 'number') {
        if (isNaN(entity)) {
            return 'nan';
        }
    }
    return type;
}

function typeIs(entity, variants) {
    return variants.includes(typeOf(entity));
}

function hasOwnProps(object, key) {
    return Object.hasOwnProperty.call(object, key);
}

export function setTempId(obj) {
    let count = new Date().getTime();

    function setId(obj) {
        for (const key in obj) {
            if (hasOwnProps(obj, key)) {
                if (typeIs(obj[key], 'object')) {
                    setId(obj[key]);
                } else if (typeIs(obj[key], 'array')) {
                    for (const elem of obj[key]) {
                        if (typeIs(elem, ['object', 'array'])) {
                            setId(elem);
                        }
                    }
                } else {
                    count++;
                    obj.tempId = count;
                }
            }
        }
    }

    setId(obj);
}

export function deleteTempId(obj) {
    for (const key in obj) {
        if (hasOwnProps(obj, key)) {
            if (typeIs(obj[key], 'object')) {
                deleteTempId(obj[key]);
            } else if (typeIs(obj[key], 'array')) {
                for (const elem of obj[key]) {
                    if (typeIs(elem, ['object', 'array'])) {
                        deleteTempId(elem);
                    }
                }
            } else {
                delete obj.tempId;
            }
        }
    }
}

export function deepClone(obj, setTempId = false) {
    const result = (typeIs(obj, 'object') && {}) || (typeIs(obj, 'array') && []);

    for (const key in obj) {
        if (hasOwnProps(obj, key)) {
            if (typeIs(obj[key], 'object')) {
                result[key] = deepClone(obj[key], setTempId);
            } else if (typeIs(obj[key], 'array')) {
                result[key] = [];
                for (const elem of obj[key]) {
                    if (typeIs(elem, ['object', 'array'])) {
                        result[key].push(deepClone(elem, setTempId));
                    } else {
                        result[key].push(elem);
                    }
                }
            } else {
                result[key] = obj[key];
                if (setTempId) result.tempId = new Date().getTime();
            }
        }
    }

    return result;
}