【问题标题】:How to restructure an array from the array itself?如何从数组本身重构数组?
【发布时间】:2020-03-19 11:11:22
【问题描述】:

我的数组是:

[{
        "Id": 1891,
        "AirportCode": "DUB",
        "AirportName": "Dublin Airport",
        "AirportCity": "Dublin",
        "Priority": 1,
        "SubPriority": 0
    },
    {
        "Id": 1921,
        "AirportCode": "DXB",
        "AirportName": "Dubai International Airport",
        "AirportCity": "Dubai",
        "Priority": 1,
        "SubPriority": 0
    },
    {
        "Id": 1680,
        "AirportCode": "DBN",
        "AirportName": "Dublin Municipal Airport",
        "AirportCity": "Dublin",
        "Priority": 2,
        "SubPriority": 1
    },
    {
        "Id": 8973,
        "AirportCode": "XNB",
        "AirportName": "United Arab Emirates - Bus Station",
        "AirportCity": "Dubai",
        "Priority": 2,
        "SubPriority": 1
    },
    {
        "Id": 6062,
        "AirportCode": "PSK",
        "AirportName": "New River Valley Airport",
        "AirportCity": "Dublin",
        "Priority": 3,
        "SubPriority": 1
    },
    {
        "Id": 1681,
        "AirportCode": "DBO",
        "AirportName": "Dubbo Airport",
        "AirportCity": "Dubbo",
        "Priority": 99,
        "SubPriority": null
    }
]

我希望它像 -

我写了如下函数,因为 AirportCity 是一样的,SubPriority 不为空

const customAirports = [];
        myArray.map((val, i, arr) => {
            let pushedInSubAirport = false;
            for (let v of customAirports) {
                if (v.AirportCity === (val.SubPriority ?
                    val.AirportCity : undefined)
                ) {
                    if (!v['SubAirport'])
                        Object.assign(v, { SubAirport: [] })
                    v['SubAirport'].push(val);
                    pushedInSubAirport = true;
                    break;
                }
            }
            if (!pushedInSubAirport)
                customAirports.push(val)
        });
        myArray = customAirports;

如果不合适,请给我建议解决方案。

【问题讨论】:

  • 转换规则是什么?

标签: javascript arrays json angular typescript


【解决方案1】:

另一种方式

this.airports.sort((a,b)=>a.Priority-b.Priority) //sort by priority
    this.airports.forEach((x,index)=>{
      const airport=this.airports.find( //try find one more on top
          (a,index2)=>a.AirportCity==x.AirportCity && index>index2)
      if (airport) //if exist
      {
        if (!airport.SubAirport) //if has not SubAirport
            airport.SubAirport=[{...x}]  //create an array with one element
        else
          airport.SubAirport.push({...x}) //add to array

        x.remove=true; //mark as "removable"
      }

    })
    this.airports=this.airports.filter(x=>!x.remove) //<--remove the removable

stackblitz

【讨论】:

  • 为什么是[{...x}],而不是[x]push(x)
  • 嵌套迭代`this.airports.forEach`和airport=this.airports.find里面可能不是很好的解决方案。
  • @Kyr,传播运算符是为了避免在添加的机场中添加属性“删除”(就像您的 ObjectAsign)。关于查找我没有发现任何问题
  • 啊哈,我明白了,传播 x 是有意义的,因为 x.remove 发生了变异。在数组上使用.find 对同一数组进行迭代不是问题,它只是 O(n2)。
【解决方案2】:

请注意数据一致性,例如null/0.

.map返回另一个数组,如果不应该,最好使用.forEach

避免在迭代结构时修改结构。

const data = [{
  "Id": 1891,
  "AirportCode": "DUB",
  "AirportName": "Dublin Airport",
  "AirportCity": "Dublin",
  "Priority": 1,
  "SubPriority": 0
}, {
  "Id": 1921,
  "AirportCode": "DXB",
  "AirportName": "Dubai International Airport",
  "AirportCity": "Dubai",
  "Priority": 1,
  "SubPriority": 0
}, {
  "Id": 1680,
  "AirportCode": "DBN",
  "AirportName": "Dublin Municipal Airport",
  "AirportCity": "Dublin",
  "Priority": 2,
  "SubPriority": 1
}, {
  "Id": 8973,
  "AirportCode": "XNB",
  "AirportName": "United Arab Emirates - Bus Station",
  "AirportCity": "Dubai",
  "Priority": 2,
  "SubPriority": 1
}, {
  "Id": 6062,
  "AirportCode": "PSK",
  "AirportName": "New River Valley Airport",
  "AirportCity": "Dublin",
  "Priority": 3,
  "SubPriority": 1
}, {
  "Id": 1681,
  "AirportCode": "DBO",
  "AirportName": "Dubbo Airport",
  "AirportCity": "Dubbo",
  "Priority": 99,
  "SubPriority": 0 // null - Inconsistent !!!
}];
const grouped = group(data);

window.result.innerHTML = JSON.stringify(grouped, null, 2);

function group(data){
  const [main, subs] = data.reduce(([main, subs], item) => {
    if (item.SubPriority === 0) {
      return [main.concat(item), subs];
    }
    const subList = subs.get(item.AirportCity) || [];
    subs.set(item.AirportCity, subList.concat(item));

    return [main, subs];
  }, [[], new Map()]);

  return main.map((item) => Object.assign(item, {SubAirport: subs.get(item.AirportCity) || []}));
}
&lt;pre id="result"/&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    相关资源
    最近更新 更多