Преобразовать JS массив в другой вид

138
22 декабря 2020, 21:50

Как правильно преобразовать массив вида:

var Orders = [
   {
    id: 1,
    title: 'Order_1',
    city: {
      id: 1,
      title: 'SPB'
    }
  },
  {
    id: 2,
    title: 'Order_2',
    city: {
      id: 1,
      title: 'SPB'
    }
  },
  {
    id: 3,
    title: 'Order_3',
    city: {
      id: 2,
      title: 'Moscow'
    }
  }
]

Во что-то такое:

var cities = [
  {
    id: 1,
    title: 'SPB',
    orders: [
      {
        id: 1,
        title: 'Order_1'
      },
      {
        id: 2,
        title: 'Order_2'
      }
    ]
  },
  {
    id: 2,
    title: 'Moscow',
    orders: [
      {
        id: 3,
        title: 'Order_1'
      }
    ]
  }
]

Сейчас использую такой вариант преобразования:

   var Orders = [
       {
        id: 1,
        title: 'Order_1',
        city: {
          id: 1,
          title: 'SPB'
        }
      },
      {
        id: 2,
        title: 'Order_2',
        city: {
          id: 1,
          title: 'SPB'
        }
      },
      {
        id: 3,
        title: 'Order_3',
        city: {
          id: 2,
          title: 'Moscow'
        }
      }
    ]
    const transformArray = (arr) => {
        const map = new Map();                  
        arr.forEach( (el) => {
            map.set(el.city, []);
        });
        arr.forEach( (el) => {
            if (map.has(el.city)) {
                let value = map.get(el.city);
                value.push({
                    id: el.id,
                    title: el.title
                });
            }
        });                    
        let structure = [];
        map.forEach( (value, key) => {
            structure.push({
                id: key.id,
                title: key.title,
                cities: value 
            });
        });
        return structure
    }    
    const Cities = transformArray(Orders);
    console.log(Cities);
Answer 1

Вот примерный вариант с reduce, о котором я писал в комментариях, чтобы избежать вложенных циклов используем для свертки Object, можно было бы и Set

var Orders = [{ 
    id: 1, title: 'Order_1', 
    city: { id: 1,title: 'SPB'} 
},{ 
    id: 2, title: 'Order_2', 
    city: {id: 1,title: 'SPB' } 
}, { 
    id: 3, title: 'Order_3', 
    city: { id: 2,title: 'Moscow'} 
}]; 
 
 
let process = d => Object.values(d.reduce((a, e) => { 
   
  //  если идентификатора города нет в аккумуляторе 
  if (!a[e.city.id]) {  
    // создаем город в аккумуляторе 
    a[e.city.id] = e.city; 
    // добавим к нему поле с массивом заказов 
    e.city.orders = []; 
  } 
 
  // Ищем в аккумуляторе город и добавляем в него заказ 
  a[e.city.id].orders.push(e);  
 
  // удаляем информацию о городе 
  delete e.city 
 
  return a; 
 
}, {})) 
 
console.log(process(Orders));

Answer 2

С использованием map и filter можно сделать

var Orders = [{ 
        id: 1, 
        title: 'Order_1', 
        city: { 
            id: 1, 
            title: 'SPB' 
        } 
    }, 
    { 
        id: 2, 
        title: 'Order_2', 
        city: { 
            id: 1, 
            title: 'SPB' 
        } 
    }, 
    { 
        id: 3, 
        title: 'Order_3', 
        city: { 
            id: 2, 
            title: 'Moscow' 
        } 
    } 
]; 
var cities = Array.from(new Set(Orders.map((a) => a.city.id)))  //Получаем уникальные ID городов 
.map(city_id => {  //Строим новый объект города 
    return { 
        id: city_id,   //Ид города 
        title: Orders.find(s => s.city.id == city_id).city.title,  //Название города 
        //Выбиараем ордера по ID города и вовращаем новый объект без свойства city 
        orders: Array.from(Orders.filter(v => v.city.id == city_id).map(b=>{return {id:b.id,title:b.title}}))  
    } 
}); 
 
console.log(JSON.stringify(cities,null,"  "));

READ ALSO
Как удалить блок, в котором находится кнопка?

Как удалить блок, в котором находится кнопка?

Есть такая начальная разметка:

137
Почему не работает $router.addRoutes?

Почему не работает $router.addRoutes?

Ситуация такая, при инициализации в объекте route три объекта маршрутов:

113
Как реализовать такой же эффект?

Как реализовать такой же эффект?

Подскажите пожалуйста, как реализовать такой же эффект у текста, как на этом сайте: https://wwwsquarespace

126
Переменная не очищается

Переменная не очищается

В subels пункты li накапливаются с каждой итерацией и не отчищаются при объявлении, а если очищать с помощью subelsempty(), то они в итоге все удаляются

113