【问题标题】:Converting lodash's `_.pull` to vanilla JS? [duplicate]将 lodash 的 `_.pull` 转换为 vanilla JS? [复制]
【发布时间】:2017-05-05 22:42:29
【问题描述】:

我在使用此函数时遇到问题,该函数会递归地从对象中删除空值:

const _ = require('lodash')

function sanitize(object) {
  Object.entries(object).forEach(([key, val]) => {
    if (
      val == null ||
      Number.isNaN(val) ||
      (typeof val === 'string' && isOnlyWhitespace(val)) ||
      (typeof val === 'object' && Object.keys(sanitize(val)).length === 0)
    ) {
      delete object[key]
    }
  });

    // Remove `undefined` values leftover from using `delete` on an array.
  if (Array.isArray(object)) {
    _.pull(object, undefined); // THIS IS THE LINE IM TRYING TO CHANGE
  }

  return object;
}

function isOnlyWhitespace(str) {
  return !(/\S/).test(str.trim());
}

我正在尝试用 vanilla JS 替换 _.pull(object, undefined),但似乎没有给出正确的输出(我尝试使用类似 filter 的东西。)

这是一个可以运行以查看两个输出的 sn-p:

// LODASH VERSION
function lodashSanitize(object) {
  Object.entries(object).forEach(([key, val]) => {
    if (
      val == null ||
      Number.isNaN(val) ||
      (typeof val === 'string' && isOnlyWhitespace(val)) ||
      (typeof val === 'object' && Object.keys(lodashSanitize(val)).length === 0)
    ) {
      delete object[key]
    }
  });

  // Remove `undefined` values leftover from using `delete` on an array.
  if (Array.isArray(object)) {
    _.pull(object, undefined); // THIS IS THE LINE IM TRYING TO CHANGE
  }

  return object;
}

// MY VERSION
function mySanitize(object) {
  Object.entries(object).forEach(([key, val]) => {
    if (
      val == null ||
      Number.isNaN(val) ||
      (typeof val === 'string' && isOnlyWhitespace(val)) ||
      (typeof val === 'object' && Object.keys(mySanitize(val)).length === 0)
    ) {
      delete object[key]
    }
  });

  // Remove `undefined` values leftover from using `delete` on an array.
  if (Array.isArray(object)) {
    object = object.filter(val => val != null) // THIS IS MY ATTEMPT
  }

  return object;
}

function isOnlyWhitespace(str) {
  return !(/\S/).test(str.trim());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<button id="lodash">Show lodash output</button>
<button id="me">Show my output</button>
<p id="output" />
<script>
  /**
   * Fiddle-related code, you can ignore this
   */ 
  const lodashBtn = document.querySelector('#lodash')
  const meBtn = document.querySelector('#me')
  const output = document.querySelector('#output')
  
  function createExampleInput() {
    const input = {
      name: 'John',
      grades: [
        90,
        undefined,
        50,
        null
      ]
    };
    
    return input;
  }
  
  lodashBtn.addEventListener('click', () => {
    output.textContent = JSON.stringify(lodashSanitize(createExampleInput()), null, 4)
  });
  
  meBtn.addEventListener('click', () => {
    output.textContent = JSON.stringify(mySanitize(createExampleInput()), null, 4)
  });
</script>

【问题讨论】:

  • 这不是真正的重复。使用直接修改数组而不是使用重复数组时,我仍然遇到问题。一旦到达Array.isArray 行,由于上面的delete,数组可能具有undefined 值。似乎_.pull 以某种方式规范化了数组并以某种方式修复了索引。

标签: javascript arrays recursion lodash


【解决方案1】:

问题是过滤器返回一个新数组。为什么不直接使用 for 循环和拼接:

if (Array.isArray(object)) {
  for (var i = object.length - 1; i >= 0; i--) {
    if (object[i] === undefined) {
      object.splice(i, 1);
    }
  }
}

【讨论】:

  • 请看我上面的评论。
  • 添加了循环实现
猜你喜欢
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 2016-10-30
  • 1970-01-01
  • 2020-07-12
  • 2016-09-17
相关资源
最近更新 更多