[算法 - 拍平系列]

173 阅读1分钟

对象拍平系列

没有用递归

juejin.cn/post/710670…

用递归怎么写

const log = console.log.bind(console, "** debug **");

const cleanObj = (k, v) => {
  // ** debug ** k A v 1   ===> key: A    value: 1
  // ** debug ** k B.C v 2 ===> key: B    value: { C: 1 }
  // ** debug ** k C.DD.E v 2  ===> key: C  value: { DD: { E: 2 } }
  let eles = k.split(".");
  let l = eles.length;
  if (l === 2) {
    // value 是 对象
    let [key, key2] = eles;
    let value = {
      [key2]: v,
    };
    return [key, value];
  } else if (l > 2) {
    // value 是 对象
    let key = eles.shift();
    let tmp = eles.join(".");
    let [newKey, newValue] = cleanObj(tmp, v);
    return [
      key,
      {
        [newKey]: newValue,
      },
    ];
  } else {
    // value 是数字
    return [k, v];
  }
};

const change = (obj) => {
  let o = {};
  for (let [k, v] of Object.entries(obj)) {
    // 第一层
    // ** debug ** k A v 1
    // ** debug ** k B.C v 2
    // ** debug ** k C.DD.E v 2
    let [newKey, newValue] = cleanObj(k, v);
    o[newKey] = newValue;
  }
  return o;
};

let obj = {
  A: 1,
  "B.C": 2,
  "C.DD.E": 2,
};
let o = f(obj);
log("o", o);

相反

const log = console.log.bind(console, "***debug***");

const isObject = (obj) => {
  return Object.prototype.toString.call(obj) === "[object Object]";
};

const cleanData = (k, arrKey, v) => {
  arrKey.push(k);
  if (isObject(v)) {
    // 是对象
    // key: g  value: {h: 300}
    return cleanData(k, arrKey, v);
  } else {
    //         f: 200,
    // key : f, value : 200p
    // 不是对象
    let newKey = arrKey.join(",");
    return [newKey, v];
  }
};

const mapDataPathAndValue = (data, arrKey = []) => {
  let r = {};
  // 遍历对象
  for (let key in data) {
    let value = data[key];
    // 拿到了 key value
    let [newKey, newValue] = cleanData(key, arrKey, value);
    r[newKey] = newValue;
  }
  return r;
};

// 方法 2
function flatObj(obj) {
  const r = {};
  const keyToStr = (k, v) => {
    if (isObject(v)) {
      // 需要加点
      for (const [key, value] of Object.entries(v)) {
        const newKey = k + "." + key;
        keyToStr(newKey, value);
      }
    } else {
      r[k] = v;
    }
  };
  // 第一次不需要 加 .
  for (const [key, value] of Object.entries(obj)) {
    keyToStr(key, value);
  }
  return r;
}

const obj = {
  a: {
    b: "hello ",
    c: {
      d: "world",
    },
  },
  e: "hello world",
};
const r = flatObj(obj);
log("r", r);

数组拍平

const flat = arr => {
  let a = []
  for(let i = 0; i < arr.length; i++) {
    let e = arr[i]
    if (Array.isArray(e)) {
      let newE = flat(e)
      a = [...a, ...newE]
    } else {
      a.push(e)
    }
  }
}

[1,[2,[3,[4,5]]]].flat(Infinity) // Infinity 递归所有层级