Как сгруппировать по объекту массива и создать массив с помощью ключа значения javascript

#javascript #node.js #adonis.js

#javascript #node.js #adonis.js

Вопрос:

Как сгруппировать по объекту массива из значений, чтобы создать новый объект массива значений

Ввод

 var promotions = [
    {
        "promotionID": 2,
        "id": 1,
        "qty": 1,
        "productID": 1,
        "product": "Nu Milk Tea 330ml",
        "operator": null
    }, {
        "promotionID": 2,
        "id": 2,
        "qty": 2,
        "productID": 2,
        "product": "Product testing 2",
        "operator": 1
    }, {
        "promotionID": 2,
        "id": 3,
        "qty": 3,
        "productID": 3,
        "product": "Golda Coffee Dolce Latte 200ml",
        "operator": 2
    }, {
        "promotionID": 3,
        "id": 4,
        "qty": 8,
        "productID": 54,
        "product": "Masker Skrineer 3ply Motif 5pcs",
        "operator": null
    }, {
        "promotionID": 3,
        "id": 5,
        "qty": 5,
        "productID": 53,
        "product": "Masker Skrineer 1ply Grey 5pcs",
        "operator": 2
    }, {
        "promotionID": 3,
        "id": 6,
        "qty": 5,
        "productID": 52,
        "product": "Oronamin C Drink 120ml",
        "operator": 1
    }]
  

Я хочу создать новый массив объектов car, сгруппированных по promotionID

Ожидаемый результат

 [
    {
        "promotionID": 2,
        "data" : [
            {
                "promotionID": 2,
                "id": 1,
                "qty": 1,
                "productID": 1,
                "product": "Nu Milk Tea 330ml",
                "operator": null
            }, {
                "promotionID": 2,
                "id": 2,
                "qty": 2,
                "productID": 2,
                "product": "Product testing 2",
                "operator": 1
            }, {
                "promotionID": 2,
                "id": 3,
                "qty": 3,
                "productID": 3,
                "product": "Golda Coffee Dolce Latte 200ml",
                "operator": 2
            } 
        ]
    },
    {
        "promotionID": 3,
        "data" : [
            {
                "promotionID": 3,
                "id": 4,
                "qty": 8,
                "productID": 54,
                "product": "Masker Skrineer 3ply Motif 5pcs",
                "operator": null
            }, {
                "promotionID": 3,
                "id": 5,
                "qty": 5,
                "productID": 53,
                "product": "Masker Skrineer 1ply Grey 5pcs",
                "operator": 2
            }, {
                "promotionID": 3,
                "id": 6,
                "qty": 5,
                "productID": 52,
                "product": "Oronamin C Drink 120ml",
                "operator": 1
            }
        ]
    }
 
]
  

Комментарии:

1. Я бы использовал цикл for или, может быть, даже метод уменьшения массива

Ответ №1:

Вы могли бы использовать reduce групповое продвижение по promotionId, а затем сопоставить записи, чтобы получить конечный результат

 var promotions = [
  {
    promotionID: 2,
    id: 1,
    qty: 1,
    productID: 1,
    product: 'Nu Milk Tea 330ml',
    operator: null
  },
  {
    promotionID: 2,
    id: 2,
    qty: 2,
    productID: 2,
    product: 'Product testing 2',
    operator: 1
  },
  {
    promotionID: 2,
    id: 3,
    qty: 3,
    productID: 3,
    product: 'Golda Coffee Dolce Latte 200ml',
    operator: 2
  },
  {
    promotionID: 3,
    id: 4,
    qty: 8,
    productID: 54,
    product: 'Masker Skrineer 3ply Motif 5pcs',
    operator: null
  },
  {
    promotionID: 3,
    id: 5,
    qty: 5,
    productID: 53,
    product: 'Masker Skrineer 1ply Grey 5pcs',
    operator: 2
  },
  {
    promotionID: 3,
    id: 6,
    qty: 5,
    productID: 52,
    product: 'Oronamin C Drink 120ml',
    operator: 1
  }
]

const res = Array.from(
  promotions
    .reduce((acc, promotion) => {
      acc.set(
        promotion.promotionID,
        (acc.get(promotion.promotionID) || []).concat(promotion)
      )
      return acc
    }, new Map)
    .entries(),
  ([promotionId, data]) => ({ promotionId, data })
)

console.log(res)  

Комментарии:

1. начиная с массива. from принимает второй аргумент, функцию map, которую вы могли бы заменить ).map(([promotionId, data]) => ({ promotionId, data })) на ,(([promotionId, data]) => ({ promotionId, data }))) (вот как я писал это, когда появился ваш ответ)

2. @JaromandaX круто, обновил мой ответ. Спасибо за ваше предложение

3. вы также можете просто сделать new Map вместо new Map() (мне нравится максимально минимизировать код: p

4. @JaromandaX ха-ха, не беспокойся, мне это нравится. Но интересно, почему без круглых скобок это все еще работает

5. см . Новый оператор … синтаксис таков new constructor[([arguments])] … все, что входит [] , необязательно… javascript был написан так — я думаю, сохранение двух символов, когда это было возможно, было важно во времена удаленного доступа 36k: p

Ответ №2:

Это мой ответ

 var promotions = [
  {
    promotionID: 2,
    id: 1,
    qty: 1,
    productID: 1,
    product: "Nu Milk Tea 330ml",
    operator: null,
  },
  {
    promotionID: 2,
    id: 2,
    qty: 2,
    productID: 2,
    product: "Product testing 2",
    operator: 1,
  },
  {
    promotionID: 2,
    id: 3,
    qty: 3,
    productID: 3,
    product: "Golda Coffee Dolce Latte 200ml",
    operator: 2,
  },
  {
    promotionID: 3,
    id: 4,
    qty: 8,
    productID: 54,
    product: "Masker Skrineer 3ply Motif 5pcs",
    operator: null,
  },
  {
    promotionID: 3,
    id: 5,
    qty: 5,
    productID: 53,
    product: "Masker Skrineer 1ply Grey 5pcs",
    operator: 2,
  },
  {
    promotionID: 3,
    id: 6,
    qty: 5,
    productID: 52,
    product: "Oronamin C Drink 120ml",
    operator: 1,
  },
];

const objectPromotion = {};

for (index in promotions) {
  const dataPromotion = objectPromotion[promotions[index].promotionID];
  console.log("dataPromotion", dataPromotion)
  if (dataPromotion) {
    dataPromotion.push(promotions[index]);
  } else {
    objectPromotion[promotions[index].promotionID] = [promotions[index]];
  }
}

const result = Object.keys(objectPromotion).map((item) => {
  return {
    promotionID: item,
    data: objectPromotion[item],
  };
});

console.log("result", result)  

Ответ №3:

вы должны использовать Lodash следующим образом.

 const _ = require('lodash');
let filteredPromotions=_.groupBy(promotions,'promotionID');
  

вывод:

 {
  '2': [
    {
      promotionID: 2,
      id: 1,
      qty: 1,
      productID: 1,
      product: 'Nu Milk Tea 330ml',
      operator: null
    },
    {
      promotionID: 2,
      id: 2,
      qty: 2,
      productID: 2,
      product: 'Product testing 2',
      operator: 1
    },
    {
      promotionID: 2,
      id: 3,
      qty: 3,
      productID: 3,
      product: 'Golda Coffee Dolce Latte 200ml',
      operator: 2
    }
  ],
  '3': [
    {
      promotionID: 3,
      id: 4,
      qty: 8,
      productID: 54,
      product: 'Masker Skrineer 3ply Motif 5pcs',
      operator: null
    },
    {
      promotionID: 3,
      id: 5,
      qty: 5,
      productID: 53,
      product: 'Masker Skrineer 1ply Grey 5pcs',
      operator: 2
    },
    {
      promotionID: 3,
      id: 6,
      qty: 5,
      productID: 52,
      product: 'Oronamin C Drink 120ml',
      operator: 1
    }
  ]
}
  

чтобы получить точный вывод, добавьте эти строки:

     filteredPropomotions = Object.keys(filteredPropomotions).map((key, index)=> {return{promotionID:key,data:filteredPropomotions[key]}}
);
  

вывод:

 [
    {
        "promotionID": 2,
        "data" : [
            {
                "promotionID": 2,
                "id": 1,
                "qty": 1,
                "productID": 1,
                "product": "Nu Milk Tea 330ml",
                "operator": null
            }, {
                "promotionID": 2,
                "id": 2,
                "qty": 2,
                "productID": 2,
                "product": "Product testing 2",
                "operator": 1
            }, {
                "promotionID": 2,
                "id": 3,
                "qty": 3,
                "productID": 3,
                "product": "Golda Coffee Dolce Latte 200ml",
                "operator": 2
            } 
        ]
    },
    {
        "promotionID": 3,
        "data" : [
            {
                "promotionID": 3,
                "id": 4,
                "qty": 8,
                "productID": 54,
                "product": "Masker Skrineer 3ply Motif 5pcs",
                "operator": null
            }, {
                "promotionID": 3,
                "id": 5,
                "qty": 5,
                "productID": 53,
                "product": "Masker Skrineer 1ply Grey 5pcs",
                "operator": 2
            }, {
                "promotionID": 3,
                "id": 6,
                "qty": 5,
                "productID": 52,
                "product": "Oronamin C Drink 120ml",
                "operator": 1
            }
        ]
    }
 
]