Búsqueda de sitios web

javascript - Cómo hacer un grupo de valores iguales


Tengo un arreglo simple y quiero recorrer el arreglo que tiene algunas claves y valores iguales, y quiero hacer un grupo de esos valores que son iguales y colocar el ítem relacionado debajo de eso.

export class AppComponent implements OnInit {

  data = [
    {
      'con': 'Usa',
      'city': 'ny',
      'town':'as'
    },
    {
      'con': 'Ger',
      'city': 'ber',
      'town':'zd'
    },
    {
      'con': 'Usa',
      'city': 'la',
      'town':'ss'
    }
  ];
  array: any[] = [];
  ngOnInit() {
    this.array = this.data;
  }
}

html :

<div *ngFor="let item of array ">
  <h3>{{item.con}}</h3>
  <p>{{item.city}}</p>
  <p>{{item.town}}</p>
  <hr>
</div>

y tengo el siguiente resultado:

Usa
ny
as
-----
Ger
ber
zd
-----
Usa
la
ss
-----

pero lo que realmente quiero es hacer un grupo de esos países con el mismo nombre y mostrar las ciudades y pueblos relacionados debajo de eso con el siguiente formato:

[{
        "con": "usa",
        "area": [{
            "city": "ny",
            "town": "as"
        }, {
            "city": "la",
            "town": "ss"
        }]
    },
    {
        "con": "ger",
        "area": [{
            "city": "ber",
            "town": "zd"
        }]
    }
]

Respuesta #1

Transforma los datos a un arreglo con los objetos consolidados, donde las propiedades cities tengan arreglos, así

[
    { con: "Usa": cities: ["ny", "la"] },
    { con: "Ger", cities: ["ber"] }
]

Puedes construir esa estructura de datos de la siguiente manera:

this.array = Array.from(
    this.data.reduce(
        (map, {con, city}) => map.set(con, (map.get(con) || []).concat(city)), 
        new Map
    ), ([con, cities]) => ({ con, cities })
);

Entonces la parte de HTML se convierte en:

<div *ngFor="let item of array ">
    <h3>{{item.con}}</h3>
    <div *ngFor="let city of item.cities ">
        <p>{{city}}</p>
    </div>
    <hr>
</div>

Respuesta #2

Puedes ordenar tu JSON antes de pasarlo a angular ngFor como se muestra a continuación,

 data = [
    {
      'con': 'Usa',
      'city': 'ny'
    },
    {
      'con': 'Ger',
      'city': 'ber'
    },
    {
      'con': 'Usa',
      'city': 'la'
    }
  ];


var expectedResult = data.sort(function (a, b) {
   return a.con.localeCompare(b.con);
});

console.log(expectedResult)
//OR
// change order as        return b.con.localeCompare(a.con);