【问题标题】:A better way to trim all elements in an object recursively?递归修剪对象中所有元素的更好方法?
【发布时间】:2020-04-08 10:22:18
【问题描述】:

如果我有类似的对象,

const obj = {
    field: {
        subfield: {
            innerObj: { a: ' asdasd  asdas . ' },
            innerArr: ['  s  ', '  ssad . '],
            innerArrObj: [ { b: '   adsad  ' } ],
        }
    }
}

我想出了这样的东西,

const trimFields = (data) =>
  _.mapValues(data, (element, k) =>
    _.isArray(element)
      ? element.map((value) =>
          _.isObject(value) ? trimFields(value) : trimText(value)
        )
      : _.isObject(element)
      ? trimFields(element)
      : trimText(element)
  );

但我想知道是否有更好/更有效的方法来做到这一点?

JSFiddle

【问题讨论】:

    标签: javascript object recursion lodash


    【解决方案1】:

    我会在函数中直接切换为数组/对象/其他,简化递归调用:

     const trimFields = (data) =>
        _.isArray(data) 
          ? data.map(trimFields)
          :  _.isObject(data) 
            ? _.mapValues(trimFields)
            : trimText(data);
    

    【讨论】:

    • 嗯,我明白你在说什么,但这会返回一个空对象。 Fiddle.
    • 啊,我以为isObject 会排除数组,它不会...
    • 我遇到了类似的问题,然后我回忆起技术上一切都是 Javascript 中的对象,尤其是数组,就_.isObject 而言。
    【解决方案2】:

    我会写一个更通用的deepMap 函数,然后用trimText 和你的对象调用它。然后它变得易于重用,并将对象导航的处理与您的实际字段转换分开。不管有没有lodash,写起来都不难。这是一个版本:

    const deepMap = (fn) => (obj) => 
      Array .isArray (obj) 
        ? obj .map (deepMap (fn))
      : Object (obj) === obj
        ? Object .fromEntries (Object .entries (obj) .map (([k, v]) => [k, deepMap (fn) (v)]))
      : // else 
        fn (obj)
    
    const trimText = field => typeof field === 'string' ? field .trim () : field;
    
    const obj = {field: {subfield: {innerObj: { a: ' asdasd  asdas . ' }, innerArr: ['  s  ', '  ssad . '], innerArrObj: [ { b: '   adsad  ' } ]}}}
    
    console .log (
      deepMap (trimText) (obj)
    )

    请注意,我简化了trimText,因为trim 内置于String.prototype

    编写这个通用版本几乎不比一次性版本难,而且您可以将它重复用于其他目的。

    deepMap (square) ({a: 1, b: [2, 3, 4], c: [{d: 5}, {d: 6}]})
    //=> {a: 1, b: [4, 9, 16], c: [{d: 25}, {d: 36}]}
    

    【讨论】:

    • : typeof obj == "object" && obj 否则会拖累null
    • @Kaiido:是的,改变了,虽然我更喜欢这个版本:Object(obj) === obj
    【解决方案3】:

    lodash 的_.transform() 函数迭代对象和数组。您可以使用_.transform() 创建递归mapValues() 函数,然后应用转换器函数(在本例中为_.trim())来处理所有值:

    const recursiveMapValues = _.curry((fn, obj) => 
      _.transform(obj, (acc, value, key) => {
          acc[key] = _.isObject(value) ?
            recursiveMapValues(fn, value)
            :
            fn(value)
      }))
      
    const trimFields = recursiveMapValues(v => _.isString(v) ? _.trim(v) : v)
    
    const obj = {"field":{"subfield":{"innerObj":{"a":" asdasd  asdas . "},"innerArr":["  s  ","  ssad . ", 3],"innerArrObj":[{"b":"   adsad  "}]}}}
    
    const result = trimFields(obj)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

    【讨论】:

      猜你喜欢
      • 2018-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 2021-10-06
      • 1970-01-01
      相关资源
      最近更新 更多