【问题标题】:Nested .unionWith, with one unique merge per level嵌套的 .unionWith,每个级别有一个唯一的合并
【发布时间】:2019-01-10 16:50:44
【问题描述】:

原始数据如下:

let AddressesBook = [
{
    "userName": "Jay12",
    "doorNumber": "1512",
    "cityID": 19,
    "city": "London",
    "countryID": 1,
    "country": "UK",
    "houseType": "private"
},
{
    "userName": "Jay12",
    "doorNumber": "2003",
    "cityID": 14,
    "city": "York",
    "countryID": 1,
    "universe": "UK",
    "houseType": "private"
},
{
    "userName": "Jay12",
    "doorNumber": "435",
    "cityID": 31,
    "city": "Washington",
    "countryID": 2,
    "universe": "USA",
    "houseType": "private"
},
{
    "userName": "Jay12",
    "doorNumber": "1123",
    "cityID": 18,
    "city": "Oxford",
    "countryID": 1,
    "universe": "UK",
    "houseType": "private"
}


];

我正在使用 Lodash 和相关唯一 ID 映射数据层次结构 被篡改的字典:

function nestMaker(list, order) {
if (_.isEmpty(order)) return [];
let groups = _.groupBy(list, _.first(order));
return _.map(groups, (children, key) => {
    let group = {};
    group[_.first(order)] = key;
    group.data = nestMaker(children, _.drop(order));
    return _.isEmpty(group.data) ? _.omit(group, 'data') : group;
  });
  }


let hierarchical = nestMaker(AddressesBook, [
"countryID",
"cityID",
"houseType",
"doorNumber"]
 );

它工作正常,但我希望在对象的每个级别中都有与 id 相关的名称。 不幸的是,您不能在两个键上使用 _.groupBy。我正在考虑将 _.unionWith 与第一次迭代分开使用,但我找不到递归使用它以省略不必要的数据的方法。

预期输出:

 let output =
  [
    {
        "countryID": "1",
        "country": "UK",
        "data": [
            {
                "cityID": "14",
                "city": "York",
                "data": [
                    {
                        "houseType": "private",
                        "data": [
                            {
                                "doorNumber": "2003"
                            }
                        ]
                    }
                ]
            },
            {
                "cityID": "18",
                "city": "Oxford",
                "data": [
                    {
                        "houseType": "private",
                        "data": [
                            {
                                "doorNumber": "1123"
                            }
                        ]
                    }
                ]
            },
            {
                "cityID": "19",
                "city": "London",
                "data": [
                    {
                        "houseType": "private",
                        "data": [
                            {
                                "doorNumber": "1512"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "countryID": "2",
        "country": "USA",
        "data": [
            {
                "cityID": "31",
                "city": "Washington",
                "data": [
                    {
                        "houseType": "private",
                        "data": [
                            {
                                "doorNumber": "435"
                            }
                        ]
                    }
                ]
            }
        ]
      }
    ];

【问题讨论】:

  • 您找到解决方案了吗?

标签: javascript recursion lodash


【解决方案1】:

您可以获取组中的第一个项目,并从该项目中提取名称(国家,城市):

const AddressesBook = [{"userName":"Jay12","doorNumber":"1512","cityID":19,"city":"London","countryID":1,"country":"UK","houseType":"private"},{"userName":"Jay12","doorNumber":"2003","cityID":14,"city":"York","countryID":1,"country":"UK","houseType":"private"},{"userName":"Jay12","doorNumber":"435","cityID":31,"city":"Washington","countryID":2,"country":"USA","houseType":"private"},{"userName":"Jay12","doorNumber":"1123","cityID":18,"city":"Oxford","countryID":1,"country":"UK","houseType":"private"}];

const nestMaker = (list, order) => {
  if (_.isEmpty(order)) return [];
  
  const idKey = _.first(order);
  const nameKey = idKey.replace('ID', '');
  let groups = _.groupBy(list, idKey);
  
  return _.map(groups, (children, key) => {
    const group = {};
    const child = _.first(children);
    
    group[idKey] = key;
    if(_.has(child, nameKey)) group[nameKey] = child[nameKey];
    
    group.data = nestMaker(children, _.drop(order));
    return _.isEmpty(group.data) ? _.omit(group, 'data') : group;
  });
}


const hierarchical = nestMaker(AddressesBook, [
  "countryID",
  "cityID",
  "houseType",
  "doorNumber"
]);

console.log(hierarchical);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

如果 id 和 name 键不遵循相同的模式,您可以将它们显式声明为 order 中的条目:

const AddressesBook = [{"userName":"Jay12","doorNumber":"1512","cityID":19,"city":"London","countryID":1,"universe":"UK","houseType":"private"},{"userName":"Jay12","doorNumber":"2003","cityID":14,"city":"York","countryID":1,"universe":"UK","houseType":"private"},{"userName":"Jay12","doorNumber":"435","cityID":31,"city":"Washington","countryID":2,"universe":"USA","houseType":"private"},{"userName":"Jay12","doorNumber":"1123","cityID":18,"city":"Oxford","countryID":1,"universe":"UK","houseType":"private"}];

const nestMaker = (list, order) => {
  if (_.isEmpty(order)) return [];
  
  const entry = _.first(order);
  const [idKey, nameKey] = Array.isArray(entry) ? entry : [entry];
  let groups = _.groupBy(list, idKey);
  
  return _.map(groups, (children, key) => {
    const group = {}; 
    const child = _.first(children);
    
    group[idKey] = key;
    if(_.has(child, nameKey)) group[nameKey] = child[nameKey];
    
    group.data = nestMaker(children, _.drop(order));
    return _.isEmpty(group.data) ? _.omit(group, 'data') : group;
  });
}


const hierarchical = nestMaker(AddressesBook, [
  ["countryID", "universe"],
  ["cityID", "city"],
  "houseType",
  "doorNumber"
]);

console.log(hierarchical);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

【讨论】:

    【解决方案2】:

    这有点手动,但确实可以。

    let AddressesBook = [{
        "userName": "Jay12",
        "doorNumber": "1512",
        "cityID": 19,
        "city": "London",
        "countryID": 1,
        "country": "UK",
        "houseType": "private"
      },
      {
        "userName": "Jay12",
        "doorNumber": "2003",
        "cityID": 14,
        "city": "York",
        "countryID": 1,
        "country": "UK",
        "houseType": "private"
      },
      {
        "userName": "Jay12",
        "doorNumber": "435",
        "cityID": 31,
        "city": "Washington",
        "countryID": 2,
        "country": "USA",
        "houseType": "private"
      },
      {
        "userName": "Jay12",
        "doorNumber": "1123",
        "cityID": 18,
        "city": "Oxford",
        "countryID": 1,
        "country": "UK",
        "houseType": "private"
      }
    
    
    ];
    database = []
    AddressesBook.forEach(a => {
      doesExist = database.some(d => (d.countryID == a.countryID))
      if (doesExist) {
        let instance = database.filter(d => d.countryID == a.countryID)[0]
        instance.data.push({
          "cityID": a.cityID,
          "city": a.city,
          "data": [{
            "houseType": a.houseType,
            "data": [{
              "doorNumber": a.doorNumber
            }]
          }]
        })
      } else {
        database.push({
          "countryID": a.countryID,
          "country": a.country,
          "data": [{
            "cityID": a.cityID,
            "city": a.city,
            "data": [{
              "houseType": a.houseType,
              "data": [{
                "doorNumber": a.doorNumber
              }]
            }]
          }]
        })
      }
    })
    
    console.log(database)

    【讨论】:

      猜你喜欢
      • 2015-10-12
      • 2014-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 2021-04-25
      • 1970-01-01
      相关资源
      最近更新 更多