Javascript-如何根据深度嵌套的数字对嵌套对象中的值进行排序?

时间:2018-12-15 14:28:18

标签: javascript

我有一个包含国家,城市和那些城市中商店的对象。我想显示(以后)的国家/地区,根据该国家/地区的城市数量排序(有效)(我的代码),然后我想根据商店的数量对城市进行排序(因此,商店数量最多的城市排在第一位)。我已经尝试了很长时间,只是无法使它正常工作,因为无论我尝试或做的任何事情都不起作用。我需要访问“ shopNum”属性,然后访问城市并进行排序,但我没有做过/做过的工作。任何帮助都将非常棒。抱歉,如果它似乎太基础了,但我尝试了一段时间,进行了研究等,迷失了。

var data = {
  Italy: {
    cityNum: 2,
    Rome: {
      shops: ['Shop123', 'shopxyz'],
      shopNum: 2
    },
    Milan: {
      shops: ['Shop1', 'shopA', 'shopD'],
      shopNum: 3
    }
  },
  USA: {
    cityNum: 1,
    Chicago: {
      shops: ['Shop123', 'shopxyz', 'shopZ'],
      shopNum: 3
    },
  },
}

var sortedCountries = Object.keys(data).sort((a, b) => {
  return data[b]["cityNum"] - data[a]["cityNum"];
}) //works fine

var sortedShops = Object.values(data).map(x => {
  Object.values(Object.keys(x).map(item => {
    if (item !== "cityNum") {
      console.log(item)
      return item;
    }
  })).map(x => console.log("item x", x))
})

sortedCities 

2 个答案:

答案 0 :(得分:1)

普通对象不是依赖某些属性顺序的正确结构。如果要对那些对象进行排序,则应改用数组。有关更多信息,请参见例如this Q&A

因此您的目标数据结构将有所不同。同时,您可以删除属性cityNumshopNum,因为一旦有了数组(它们具有length属性),它们就变得多余了。

我将由内而外地工作,并开始创建带有城市的排序数组,然后最后根据城市数量对这些子结构进行排序:

var data = {Italy: {cityNum: 2,Rome: {shops: ['Shop123', 'shopxyz'],shopNum: 2},Milan: {shops: ['Shop1', 'shopA', 'shopD'],shopNum: 3}},USA: {cityNum: 1,Chicago: {shops: ['Shop123', 'shopxyz', 'shopZ'],shopNum: 3},},}
var sortedCountries = Object.entries(data)
    .map(([country, cities]) => ({ 
        country, 
        cities: Object.keys(cities)
            .filter(prop => prop !== "cityNum")
            .sort((a, b) => cities[b].shops.length - cities[a].shops.length)
            .map(city => ({
                city,
                shops: cities[city].shops
            }))
    }))
    .sort((a, b) => b.cities.length - a.cities.length)
console.log(sortedCountries);

答案 1 :(得分:0)

您可以使用包含所有城市的.reduce来构造一个名为allCities的新对象。然后,使用与在cityNum上使用的排序函数相同的功能,但是这次将应用于allCities和属性shopNum上。

代码如下:

const data={Italy:{cityNum:2,Rome:{shops:["Shop123","shopxyz"],shopNum:2},Milan:{shops:["Shop1","shopA","shopD"],shopNum:3}},USA:{cityNum:1,Chicago:{shops:["Shop123","shopxyz","shopZ"],shopNum:3}}};

const sortedCountries = Object.keys(data).sort((a, b) => {
  return data[b]["cityNum"] - data[a]["cityNum"];
});

const allShops = Object.values(data).reduce((allCities, country) => {
  
  // extract the cityNum from the country object, the rest are cities 
  const { cityNum, ...cities } = country;
  
  // return an object containing all cities + the cities from the current country 
  return { ...allCities, ...cities };

}, {});


const sortedShops = Object.keys(allShops).sort((a, b) => {
  return allShops[b]["shopNum"] - allShops[a]["shopNum"];
});

console.log(sortedCountries)
console.log(sortedShops);