fedono / fe-questions

1 stars 0 forks source link

实现lodash 相关函数 _.chunk() _.get() #46

Open fedono opened 9 months ago

fedono commented 9 months ago

chunk([1,2,3,4,5], 1)
// [[1], [2], [3], [4], [5]]

chunk([1,2,3,4,5], 2)
// [[1, 2], [3, 4], [5]]

chunk([1,2,3,4,5], 3)
// [[1, 2, 3], [4, 5]]

chunk([1,2,3,4,5], 4)
// [[1, 2, 3, 4], [5]]

chunk([1,2,3,4,5], 5)
// [[1, 2, 3, 4, 5]]

解法,来源 implement-lodash-chunk

/** 
 * @param {any[]} items
 * @param {number} size
 * @returns {any[][]}
 */
function chunk(items, size) {
  if (size === 0) return [];
  const res = [];
  for (let i=0; i<items.length; i=i+size) {
    res.push(items.slice(i, i+size));
  }
  return res;
}
fedono commented 9 months ago

实现 _.get

function get(source, path, defaultValue = undefined) {
  const paths = Array.isArray(path)
    ? path
    : path.replaceAll('[', '.').replaceAll(']', '').split('.');

  let curNode = source;
  let curPath = paths.shift();
  while (curPath && curNode) {
    curNode = curNode[curPath];
    curPath = props.shift();
  }

  return curNode === undefined ? defaultValue : curNode;
}

const obj = {
  a: {
    b: {
      c: [1, 2, 3]
    }
  }
};

console.log(get(obj, 'a.b.c')); // [1,2,3]
console.log(get(obj, 'a.b.c.0')); // 1
console.log(get(obj, 'a.b.c[1]')); // 2
console.log(get(obj, ['a', 'b', 'c', '2'])); // 3
console.log(get(obj, 'a.b.c[3]')); // undefined
console.log(get(obj, 'a.c', 'bfe')); // 'bfe'

或者

function get(source, path, defaultValue = undefined) {
  // your code here
  const parts = Array.isArray(path) ? path : path
    .replaceAll("[", ".")
    .replaceAll("]", "")
    .split(".")

  if (parts.length === 0) {
    return defaultValue
  }

  for (const part of parts) {
    if (source[part] === undefined) {
      return defaultValue
    }
    source = source[part]
  }
  return source
}
fedono commented 9 months ago

实现 set

const obj = {
  a: {
    b: {
      c: [1,2,3]
    }
  }
}
set(obj, 'a.b.c', 'BFE')
console.log(obj.a.b.c) // "BFE"

set(obj, 'a.b.c.0', 'BFE')
console.log(obj.a.b.c[0]) // "BFE"

set(obj, 'a.b.c[1]', 'BFE')
console.log(obj.a.b.c[1]) // "BFE"

set(obj, ['a', 'b', 'c', '2'], 'BFE')
console.log(obj.a.b.c[2]) // "BFE"

set(obj, 'a.b.c[3]', 'BFE')
console.log(obj.a.b.c[3]) // "BFE"

set(obj, 'a.c.d[0]', 'BFE')
// valid digits treated as array elements
console.log(obj.a.c.d[0]) // "BFE"

set(obj, 'a.c.d.01', 'BFE')
// invalid digits treated as property string
console.log(obj.a.c.d['01']) // "BFE"
function set(obj, path, value) {
  path = Array.isArray(path) ? path :  path.replace('[', '.').replace(']', '').split('.');
  src = obj;
  path.forEach((key, index, array) => {
    if (index == path.length - 1) {
      src[key] = value;
    } else {
      if (!src.hasOwnProperty(key)) { // if the key doesn't exist on object
        const next = array[index + 1];
        src[key] = String(Number(next)) === next ? [] : {}; // create a new object if next is item in array is not a number
      }
      src = src[key];
    }
  })
}