简体   繁体   English

递归修剪 object 中所有元素的更好方法?

[英]A better way to trim all elements in an object recursively?

If I have an object like,如果我有一个 object 之类的,

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

I've come up with something like this,我想出了这样的东西,

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

But I'm wondering if there is a better / more efficient way to do this?但我想知道是否有更好/更有效的方法来做到这一点?

JSFiddle JSFiddle

I'd switch for array / object / other directly in the function, simplifying the recursive call:我会直接在 function 中切换数组/object/其他,简化递归调用:

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

I would write a more general deepMap function and then call it with trimText and your object.我会写一个更通用的deepMap function,然后用trimText和你的 object 调用它。 It then becomes easily reusable, and it separates out the handling of object navigation from your actual field transformation.然后它变得易于重用,并将 object 导航的处理与您的实际字段转换分开。 It's not hard to write, either with or without lodash.不管有没有lodash,写起来都不难。 Here's one version:这是一个版本:

 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) )

Note that I simplified trimText , since trim is built into String.prototype .请注意,我简化trimText ,因为trim内置于String.prototype中。

Writing this generic version is pretty much no more difficult than a one-off version, and you can reuse it for other purposes.编写这个通用版本几乎不比一次性版本更难,您可以将它重用于其他目的。

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

The lodash's _.transform() function iterates both objects and arrays. lodash 的_.transform() function 迭代两个对象和 arrays。 You can create a recursive mapValues() function using _.transform() , and then apply a transformer function ( _.trim() in this case) to handle all values:您可以使用_.transform()创建递归mapValues() function ,然后应用转换器 function (在这种情况下为_.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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM