【问题标题】:flatten nested object using lodash使用 lodash 展平嵌套对象
【发布时间】:2017-03-07 10:09:14
【问题描述】:

lodash 的 flatten、flattenDeep 或 flattenDepth 只接受数组。如何展平嵌套对象?

var data = {
  "dates": {
    "expiry_date": "30 sep 2018",
    "available": "30 sep 2017",
    "min_contract_period": [{
      "id": 1,
      "name": "1 month",
      "value": false
    }, {
      "id": 2,
      "name": "2 months",
      "value": true
    }, {
      "id": 3,
      "name": "3 months",
      "value": false
    }]
  },
  "price": {
    "curreny": "RM",
    "min": 1500,
    "max": 2000
  }
}

我希望嵌套属性是第一级,比如 expiry_date 应该是第 1 级,而不是在日期内,而且我认为日期应该消失,不再需要它。我可以手动完成,使用 map() 但我希望使用 lodash 来简化任务。

【问题讨论】:

  • 您能否提供示例代码,说明您希望输出在任务完成后如何显示?说 1 级并且事情“应该消失”可能会混淆一个例子很清楚的问题
  • lodash#1228 中提出了这个问题/提出的功能,并提出了“解决方案”以查看flat package

标签: javascript ecmascript-6 lodash


【解决方案1】:

最简单的解决方案之一是将嵌套对象与父对象合并,

_.merge(data, data.dates);

这会将所有data.dates 属性带入data。然后删除data.dates

delete data.dates

【讨论】:

  • 我搜索了几个小时以找到一种简单、明智和直观的方法来做到这一点,这是迄今为止最好的答案。
【解决方案2】:

ES6 版本:

var data = {
  "dates": {
    "expiry_date": "30 sep 2018",
    "available": "30 sep 2017",
    "min_contract_period": [{
      "id": 1,
      "name": "1 month",
      "value": false
    }, {
      "id": 2,
      "name": "2 months",
      "value": true
    }, {
      "id": 3,
      "name": "3 months",
      "value": false
    }]
  },
  "price": {
    "curreny": "RM",
    "min": 1500,
    "max": 2000
  }
};

var {dates: {expiry_date, ...dates}, ...rest} = data;
var flatData = {dates, expiry_date, ...rest}
console.log(flatData)

需要注意的一点是,您必须小心深度嵌套的析构。在这个例子中,如果data.datesundefined 并且你尝试对其进行解构,则会抛出错误。

【讨论】:

    【解决方案3】:

    你可以.merge().get()_.pick()的结果:

    var data = {"dates": {"expiry_date": "30 sep 2018","available": "30 sep 2017","min_contract_period": [{"id": 1,"name": "1 month","value": false}, {"id": 2,"name": "2 months","value": true}, {"id": 3,"name": "3 months","value": false}]},"price": {"curreny": "RM","min": 1500,"max": 2000}},
        result = _.merge(_.get(data, 'dates'), _.pick(data, 'price'));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

    【讨论】:

      【解决方案4】:

      来自Andreyanswer

      function flattenObject(o, prefix = '', result = {}, keepNull = true) {
        if (_.isString(o) || _.isNumber(o) || _.isBoolean(o) || (keepNull && _.isNull(o))) {
          result[prefix] = o;
          return result;
        }
      
        if (_.isArray(o) || _.isPlainObject(o)) {
          for (let i in o) {
            let pref = prefix;
            if (_.isArray(o)) {
              pref = pref + `[${i}]`;
            } else {
              if (_.isEmpty(prefix)) {
                pref = i;
              } else {
                pref = prefix + '.' + i;
              }
            }
            flattenObject(o[i], pref, result, keepNull);
          }
          return result;
        }
        return result;
      }
      

      【讨论】:

        【解决方案5】:

        这会用任何深度的嵌套对象和数组来展平对象。结果对象中的键是输入对象中属性的完整路径

        public static flattenObject(o: any, prefix?: string, result?: any): any {
        
            prefix = prefix ? prefix : '';
            result = result ? result : {};
        
            if (_.isString(o) || _.isNumber(o) || _.isBoolean(o)) {
                result[prefix] = o;
                return result;
            }
        
            if (_.isArray(o) || _.isPlainObject(o)) {
                for (let i in o) {
        
                    let pref = prefix;
                    if (_.isArray(o)) {
                        pref = pref + `[${i}]`;
                    } else {
                        if (_.isEmpty(prefix)) {
                            pref = i;
                        } else {
                            pref = prefix + '.' + i;
                        }
                    }
        
                    Utils.flattenObject(o[i], pref, result);
                }
                return result;
            }
        
        
            return result;
        }
        

        【讨论】:

          【解决方案6】:

          如果你需要展平整个对象,不仅是它的“日期”属性,这样的东西应该可以工作,你甚至不需要 lodash:

          function flattenObject(obj) {
            const result = {};
          
            Object.values(obj).forEach(nestedObject => {
              Object.assign(result, nestedObject);
            });
          
            return result;
          }
          

          【讨论】:

            猜你喜欢
            • 2017-10-19
            • 1970-01-01
            • 2021-11-29
            • 2020-09-05
            • 2018-10-24
            • 1970-01-01
            • 1970-01-01
            • 2021-12-11
            • 2017-07-02
            相关资源
            最近更新 更多