2020-04-13
阿里巴巴二面凉经 flatten扁平化对象与数组

在线笔试的时候写错了一点点 太可惜了哎 还是基础不够扎实。。。

const input = {
  a: 1,
  b: [ 1, 2, { c: true }, [ 3 ] ],
  d: { e: 2, f: 3 },
  g: null,
}

function flatten(input) {
  // 需要实现的代码
}

flatten(input);

// 返回
{
  "a": 1,
  "b[0]": 1,
  "b[1]": 2,
  "b[2].c": true,
  "b[3][0]": 3,
  "d.e": 2,
  "d.f": 3,
  // "g": null, 值为null或者undefined,丢弃
};

题解:
思路1:转为对象后递归
function flatten(obj) {
let result = {};
if (Array.isArray(obj)) { // 初始的input是array 转为object
let tmp = {};
obj.forEach((item, index) => {
let attr = '[' + index + ']';
tmp[attr] = obj[index];
});
result = flatten(tmp);
} else {
Object.keys(obj).forEach(key => { // 通过key遍历对象
if (typeof obj[key] === 'object') {
// console.log(Object.prototype.toString.call(obj[key])) 也可以用这个判断准确的类型
// if (Array.isArray(obj[key])) {
if (Object.prototype.toString.call(obj[key]) === '[object Array]') { // 如果某项值为array
let tmp = {};
obj[key].forEach((item, index) => {
let attr = key + '[' + index + ']';
tmp[attr] = obj[key][index];
});
result = Object.assign({}, result, flatten(tmp)); // 转为对象后递归再与原来的result合并
}
else if (Object.prototype.toString.call(obj[key]) === '[object Object]') { // 如果是对象
let tmp = {};
Object.keys(obj[key]).forEach(k => {
let attr = key + '.' + k;
tmp[attr] = obj[key][k];
});
result = Object.assign({}, result, flatten(tmp)); // 递归后合并
}
} else {
if (obj[key]) { // 避免出现undefined
result[key] = obj[key];
}
}
});
}
return result;
}

思路2:记录前key递归

function flatten(input) {
let result = {} function flat(prekey, ipt) {
if (ipt) {
let temp = {}
if (Object.prototype.toString.call(ipt) === '[object Object]') {
for (let key in ipt) {
temp = Object.assign(temp, flat(prekey + '.' + key, ipt[key]))
}
} else if (Array.isArray(ipt)) {
for (let key in ipt) {
temp = Object.assign(temp, flat(prekey + '[' + key + ']', ipt[key]))
}
} else {
temp[prekey] = ipt
}
return temp
}
} for (let key in input) {
result = Object.assign(result, flat(key, input[key]))
}
return result
}

思路2: 贪心算法

创建两个数组分别存存在的可能和对应字符
从大往下算 每当Num>num[0] 那么result就+一次chars[0]
直到num < num[0] 那么把nums[0]和chars[0]删掉
循环上面的操作

-->