开发中常见的数据处理

256 阅读3分钟

数组扁平化

常规数组扁平化

let arr = [
    [1, 2, 2],
    [3, 4, 5, 5],
    [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10

];

转变为如下格式

[1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

基于递归实现

function myFlat(arr){
  var result = [];
  var next = function next(arr) {
      arr.forEach(function (item) {
          if (Array.isArray(item)) {
              next(item);
              return;
          }
          result.push(item);
      });
  };
  next();
  return result;
}

基于concat方式进行逐级降维

while (
    arr.some(function (item) {
        return Array.isArray(item);
    })
) {
   
    arr = [].concat.apply([], arr);
}

toString

arr = arr.toString().split(',').map(function (item) {
    return +item;
});

特殊数组扁平化

省市县三级数据,现在要编写 getNameByCode,通过输入的code值,获取name值!

let address = [{    "code": "11",    "name": "北京市",    "children": [{        "code": "1101",        "name": "市辖区",        "children": [{            "code": "110101",            "name": "东城区"        }, {            "code": "110102",            "name": "西城区"        }]
    }]
}, {
    "code": "13",
    "name": "河北省",
    "children": [{
        "code": "1301",
        "name": "石家庄市",
        "children": [{
            "code": "130102",
            "name": "长安区"
        }, {
            "code": "130104",
            "name": "桥西区"
        }]
    }, {
        "code": "1302",
        "name": "唐山市",
        "children": [{
            "code": "130202",
            "name": "路南区"
        }, {
            "code": "130203",
            "name": "路北区"
        }]
    }]
}];

方案1:递归查找「深度优先原则」

const getNameByCode = function getNameByCode(address, code) {
    let result = "";
    const next = arr => {
        for (let i = 0; i < arr.length; i++) {
            let { code: codeItor, name, children } = arr[i];
            if (codeItor == code) {
                result = name;
                break;
            }
            if (Array.isArray(children)) next(children);
        }
    };
    next(address);
    return result;
} 

方案2: 先扁平化处理「广度优先原则」

const getNameByCode = (function (address) {
    // 先扁平化处理「广度优先原则」
    let result = [];
    const next = arr => {
        // 先把本级处理好
        let temp = arr.map(item => {
            return {
                code: item.code,
                name: item.name
            };
        });
        result = result.concat(temp);
        // 再看是否有children,如果存在,再处理下一级
        arr.forEach(item => {
            if (item.children) next(item.children);
        });
    };
    next(address);
 
    // 返回按照code查找的方法「去扁平化后的数组中查找」
    return function getNameByCode(code) {
        let item = result.find(item => item.code == code);
        return item ? item.name : '';
    };
})(address);
console.log(getNameByCode('130102')); //"长安区"
console.log(getNameByCode('1302')); //"唐山市"

方法二:


        const getNameByCode = (address, code) => {
            let p = address,
                result = "";
            while (p.length > 0) {
                let item = p.shift()
                let { code: itemCode, name, children } = item;
                if (itemCode === code) {
                    result = name;
                    break;
                }
                if (children) {
                    children.forEach((child)=>{
                        p.push(child)
                    })
                }

            }
                return result
        }

一维数组转树结构

let data = [
    { id: 0, parentId: null, text: '北京市' },
    { id: 1, parentId: 0, text: '昌平区' },
    { id: 2, parentId: 0, text: '海淀区' },
    { id: 3, parentId: null, text: '河北省' },
    { id: 4, parentId: null, text: '山西省' },
    { id: 5, parentId: 3, text: '承德市' },
    { id: 6, parentId: 3, text: '石家庄市' }
];

最终结果:

[
    {
        id: 0, parentId: null, text: '北京市',
        childen: [
            { id: 1, parentId: 0, text: '昌平区' },
            { id: 2, parentId: 0, text: '海淀区' }
        ]
    },
    {
        id: 3, parentId: null, text: '河北省',
        childen: [
            { id: 5, parentId: 3, text: '承德市' },
            { id: 6, parentId: 3, text: '石家庄市' }
        ]
    },
    { id: 4, parentId: null, text: '山西省' }
];
const list2Tree = function list2Tree(data) {
    // 把data变为Map数据结构
    let map = new Map(),
        result = [];
    data.forEach(item => {
        map.set(item.id, item);
    });
    // 迭代数组中的每一项,根据parentId做不同的处理
    data.forEach(item => {
        let { parentId } = item,
            parent;
        // parentId是null的,说明其就是第一级,我们把其加入到result中即可
        if (parentId === null) {
            result.push(item);
            return;
        }
        // parentId不是null的,说明其实第二级,我们根据parentId找到其所属的第一级,把当前迭代这一项作为其children加入进去
        parent = map.get(parentId);
        parent.children ? parent.children.push(item) : parent.children = [item];
    });
    return result;
};

对象扁平化

const obj = {
    a: {
        b: 1,
        c: 2,
        d: { e: 3, 2: 200 },
    },
    b: [1, 2, { a: 3, b: 4 }],
    c: 1,
    1: 100,
    x: {}
};

转化为:

let objFlatten = {
    1: 100,
    'a.b': 1,
    'a.c': 2,
    'a.d.e': 3,
    'a.d[2]': 200,
    'b[0]': 1,
    'b[1]': 2,
    'b[2].a': 3,
    'b[2].b': 4,
    'c': 1,
    x: {}
}; 
 
function flatten(obj) {
        let result = {};
        const next = (obj, attr) => {
            let isObject = _.isPlainObject(obj),
                isArray = Array.isArray(obj);
            if (isArray || isObject) {
                // 考虑为空的情况
                if (isObject && _.isEmptyObject(obj)) {
                    result[attr] = {};
                    return;
                }
                if (isArray && obj.length === 0) {
                    result[attr] = [];
                    return;
                }
                // 不为空的情况则迭代处理
                _.each(obj, (value, key) => {
                    let temp = isNaN(key) ? `.${key}` : `[${key}]`;
                    next(value, attr ? attr + temp : key);
                });
                return;
            }
            result[attr] = obj;
        };
        next(obj, "");
        return result;
    }
});
console.log(Object.flatten(obj));