web-dev-qa-db-ja.com

lodashを使用してネストされたオブジェクトを平坦化する

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を使用したいと考えています。

10
Giala Jefferson

最も簡単な解決策の1つは、ネストされたオブジェクトを親とマージすることです。

_.merge(data, data.dates);

これにより、すべてのdata.datesプロパティがdataになります。次にdata.datesを削除します

delete data.dates
10
RaR

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)

注意すべきことの1つは、深くネストされた破壊に注意する必要があることです。この例では、data.datesundefinedであり、それを分解しようとすると、エラーがスローされます。

5
T.Chmelevskij

。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>
2
Yosvel Quintero

Andreyanswer から

function flattenObject(o, prefix = '', 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;
        }
      }
      flattenObject(o[i], pref, result);
    }
    return result;
  }
  return result;
}
0
Vincent

これは、ネストされたオブジェクトと任意の深さの配列でオブジェクトを平坦化します。結果のオブジェクトのキーは、入力オブジェクトのプロパティへのフルパスです

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;
}
0
Andrey