美文网首页
常见工具函数

常见工具函数

作者: small_zeo | 来源:发表于2022-04-19 16:11 被阅读0次
// is object
export function isObject(object) {
    return Object.prototype.toString.call(object) === '[object Object]';
}

// is arguments
function isArguments(object) {
    return Object.prototype.toString.call(object) === '[object Arguments]';
}

// 定义的数据推导出schema 类型
export const guessType = function guessType(value) {
    if (Array.isArray(value)) {
        return 'array';
    } if (typeof value === 'string') {
        return 'string';
    } if (value == null) {
        return 'null';
    } if (typeof value === 'boolean') {
        return 'boolean';
        // eslint-disable-next-line no-restricted-globals
    } if (!isNaN(value)) {
        return 'number';
    } if (typeof value === 'object') {
        return 'object';
    }
    // Default to string if we can't figure it out
    return 'string';
};

export function union(arr1, arr2) {
    return [...new Set([...arr1, ...arr2])];
}

// Recursively merge deeply nested schemas.
// The difference between mergeSchemas and mergeObjects
// is that mergeSchemas only concats arrays for
// values under the "required" keyword, and when it does,
// it doesn't include duplicate values.
export function mergeSchemas(obj1, obj2) {
    const acc = Object.assign({}, obj1); // Prevent mutation of source object.
    // eslint-disable-next-line no-shadow
    return Object.keys(obj2).reduce((acc, key) => {
        const left = obj1 ? obj1[key] : {};
        const right = obj2[key];
        if (obj1 && obj1.hasOwnProperty(key) && isObject(right)) {
            acc[key] = mergeSchemas(left, right);
        } else if (
            obj1
            && obj2
            && (getSchemaType(obj1) === 'object' || getSchemaType(obj2) === 'object')
            && key === 'required'
            && Array.isArray(left)
            && Array.isArray(right)
        ) {
            // Don't include duplicate values when merging
            // "required" fields.
            acc[key] = union(left, right);
        } else {
            acc[key] = right;
        }
        return acc;
    }, acc);
}

// 合并对象数据
export function mergeObjects(obj1, obj2, concatArrays = false) {
    // Recursively merge deeply nested objects.
    const preAcc = Object.assign({}, obj1); // Prevent mutation of source object.
    if (!isObject(obj2)) return preAcc;

    return Object.keys(obj2).reduce((acc, key) => {
        const left = obj1 ? obj1[key] : {};
        const right = obj2[key];
        if (obj1 && obj1.hasOwnProperty(key) && isObject(right)) {
            acc[key] = mergeObjects(left, right, concatArrays);
        } else if (concatArrays && Array.isArray(left) && Array.isArray(right)) {
            acc[key] = left.concat(right);
        } else {
            acc[key] = right;
        }
        return acc;
    }, preAcc);
}

// 获取给定 schema 类型。
export function getSchemaType(schema) {
    const { type } = schema;

    // 通过const 申明的常量 做类型推断
    if (!type && schema.const) {
        return guessType(schema.const);
    }

    // 枚举默认字符串
    if (!type && schema.enum) {
        return 'string';
    }

    // items 推断为 array 类型
    if (!type && (schema.items)) {
        return 'array';
    }

    // anyOf oneOf 不申明 type 字段
    if (!type && (schema.properties || schema.additionalProperties)) {
        return 'object';
    }

    if (type instanceof Array && type.length === 2 && type.includes('null')) {
        return type.find(curType => curType !== 'null');
    }

    return type;
}

// 深度相等对比
export function deepEquals(a, b, ca = [], cb = []) {
    // Partially extracted from node-deeper and adapted to exclude comparison
    // checks for functions.
    // https://github.com/othiym23/node-deeper
    if (a === b) {
        return true;
    } if (typeof a === 'function' || typeof b === 'function') {
        // Assume all functions are equivalent
        // see https://github.com/mozilla-services/react-jsonschema-form/issues/255
        return true;
    } if (typeof a !== 'object' || typeof b !== 'object') {
        return false;
    } if (a === null || b === null) {
        return false;
    } if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime();
    } if (a instanceof RegExp && b instanceof RegExp) {
        return (
            a.source === b.source
            && a.global === b.global
            && a.multiline === b.multiline
            && a.lastIndex === b.lastIndex
            && a.ignoreCase === b.ignoreCase
        );
    } if (isArguments(a) || isArguments(b)) {
        if (!(isArguments(a) && isArguments(b))) {
            return false;
        }
        const slice = Array.prototype.slice;
        return deepEquals(slice.call(a), slice.call(b), ca, cb);
    }
    if (a.constructor !== b.constructor) {
        return false;
    }

    const ka = Object.keys(a);
    const kb = Object.keys(b);
    // don't bother with stack acrobatics if there's nothing there
    if (ka.length === 0 && kb.length === 0) {
        return true;
    }
    if (ka.length !== kb.length) {
        return false;
    }

    let cal = ca.length;
    // eslint-disable-next-line no-plusplus
    while (cal--) {
        if (ca[cal] === a) {
            return cb[cal] === b;
        }
    }
    ca.push(a);
    cb.push(b);

    ka.sort();
    kb.sort();
    // eslint-disable-next-line no-plusplus
    for (let j = ka.length - 1; j >= 0; j--) {
        if (ka[j] !== kb[j]) {
            return false;
        }
    }

    let key;
    // eslint-disable-next-line no-plusplus
    for (let k = ka.length - 1; k >= 0; k--) {
        key = ka[k];
        if (!deepEquals(a[key], b[key], ca, cb)) {
            return false;
        }
    }

    ca.pop();
    cb.pop();

    return true;
}

// 只保证同时生成不重复
export const genId = (function genIdFn() {
    let preKey = `${+new Date()}`;
    let key = 0;
    return () => {
        const curTimestamp = `${+new Date()}`;
        if (curTimestamp === preKey) {
            key += 1;
        } else {
            // 重置 key
            key = 0;
        }

        preKey = curTimestamp;
        return `${preKey}x${key}`;
    };
}());

// 空对象
export function isEmptyObject(obj) {
    if (!obj) return true;

    for (const key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            return false;
        }
    }
    return true;
}

// 过滤和转换对象的key
export function filterObject(obj, filterFn) {
    return Object.entries(obj).reduce((preVal, [key, value]) => {
        const newKey = filterFn(key, value);
        if (undefined !== newKey) {
            preVal[newKey] = value;
        }
        return preVal;
    }, {});
}

const f = s => `0${s}`.substr(-2);
export function parseDateString(dateString, includeTime = true) {
    if (!dateString) {
        return {
            year: -1,
            month: -1,
            day: -1,
            hour: includeTime ? -1 : 0,
            minute: includeTime ? -1 : 0,
            second: includeTime ? -1 : 0,
        };
    }
    const date = new Date(dateString);
    if (Number.isNaN(date.getTime())) {
        throw new Error(`Unable to parse date ${dateString}`);
    }
    return {
        year: date.getFullYear(),
        month: f(date.getMonth() + 1), // oh you, javascript.
        day: f(date.getDate()),
        hour: f(includeTime ? date.getHours() : 0),
        minute: f(includeTime ? date.getMinutes() : 0),
        second: f(includeTime ? date.getSeconds() : 0),
    };
}

export function toDateString(
    {
        year, month, day, hour = 0, minute = 0, second = 0
    },
    time = true
) {
    const utcTime = Date.UTC(year, month - 1, day, hour, minute, second);
    const datetime = new Date(utcTime).toJSON();
    return time ? datetime : datetime.slice(0, 10);
}

export function pad(num, size) {
    let s = String(num);
    while (s.length < size) {
        s = `0${s}`;
    }
    return s;
}

// dataUrl 转 Blob文件对象
export function dataURItoBlob(dataURI) {
    // Split metadata from data
    const splitted = dataURI.split(',');
    // Split params
    const params = splitted[0].split(';');
    // Get mime-type from params
    const type = params[0].replace('data:', '');
    // Filter the name property from params
    const properties = params.filter(param => param.split('=')[0] === 'name');
    // Look for the name and use unknown if no name property.
    let name;
    if (properties.length !== 1) {
        name = 'unknown';
    } else {
        // Because we filtered out the other property,
        // we only have the name case here.
        name = properties[0].split('=')[1];
    }

    // Built the Uint8Array Blob parameter from the base64 string.
    const binary = atob(splitted[1]);
    const array = [];
    // eslint-disable-next-line no-plusplus
    for (let i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    // Create the blob object
    const blob = new window.Blob([new Uint8Array(array)], { type });

    return { blob, name };
}

// 字符串首字母小写
export function lowerCase(str) {
    if (undefined === str) return str;
    return String(str).replace(/^./, s => s.toLocaleLowerCase());
}

// 最大公约数
export function gcd(a, b) {
    if (b === 0) return a;
    return gcd(b, a % b);
}

// 最小公倍数
export function scm(a, b) {
    return (a * b) / gcd(a, b);
}

// 打开新页面
export function openNewPage(url, target = '_blank') {
    const a = document.createElement('a');
    a.style.display = 'none';
    a.target = target;
    a.href = url;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

相关文章

  • 常见工具函数

  • Python官方教程阅读总结-流程控制

    常见的流程控制工具包括:条件控制语句, 循环控制语句,函数等,下面依次介绍 1. if 语句 用于条件判断,常见的...

  • Oracle 单行函数

    常见字符函数 常见数值函数 四舍五入: 去尾: 求模(取余): 常见日期函数 sysdate 获取系统当前时间(数...

  • 常见函数

    1.打开页面: 应用场景:添加和编辑grid记录,后缀带_add或者_edit的func(特殊:authorize...

  • 常见函数

    概念: 将一组逻辑语句封装在方法体中,对外暴露方法名 调用: select 函数名(实参列表)from表明;...

  • 常见函数

    函数的定义:给定一个数集A,对A施加一个对应的法则/映射f,记做:f(A),那么可以得到另外一个数集B,也就是可以...

  • 常见函数

    switch-case语句: 多重if语句: 分组函数:image.png distinct去重:image.pn...

  • java笔记--整合使用

    创建一个数组工具类ArrayTool,对常见的对数组操作的方法进行封装: 主函数类ArrayToolDemo进行调用:

  • 知识分享之Golang——一个常见word、excel转换pdf

    知识分享之Golang——一个常见word、excel转换pdf的工具函数 背景 知识分享之Golang篇是我在日...

  • Python学习笔记七:内置函数补充,函数作用域,闭包及递归

    一、常见的内置函数 1. 查看内置函数: 2. 常见函数: 3. 进制转换函数: 4. 补充: (1) enume...

网友评论

      本文标题:常见工具函数

      本文链接:https://www.haomeiwen.com/subject/uigsertx.html