Javascript Массив дубликатов объединения объектов - PullRequest
0 голосов
/ 13 сентября 2018

Мне нужно найти дубликаты по коду страны и объединить их в один объект

Структура массива:

[{...},{...}]

Предметы

{Country_Code: "RU", Country: "Russia", Provider: "Shell1", Price: "0.123"},
{Country_Code: "EN", Country: "Russia", Provider: "Shell", Price: "0.76856"},
{Country_Code: "RO", Country: "Russia", Provider: "Shell", Price: "0.563"},
{Country_Code: "RU", Country: "Russia", Provider: "Shell2", Price: "0.90890"},
{Country_Code: "RU", Country: "Russia", Provider: "Shell3", Price: "0.90"}

Мне нужно получить массив объекта

[{Country_Code: "RU", Country: "Russia", Provider: "Shell1 - 0.123</br>Shell2 - 0.90890</br>Shell3 - 0.90", Price: "0.123"},
{Country_Code: "EN", Country: "Russia", Provider: "Shell", Price: "0.76856"},
{Country_Code: "RO", Country: "Russia", Provider: "Shell", Price: "0.563"}]

Если подумать, что-то вроде

var NewArr =[],NewObj ={};
data.forEach(function(dataItem,index) {
    CC = dataItem.Country_Code;
    counts[CC]= (counts[CC]||0) + 1; // Count duplicates
        if(counts[CC]>1){
            NewObj.Country_Code = dataItem.Country_Code;
            NewObj.Country = dataItem.Country;
            NewObj.Provider = dataItem.Provider + " - " + dataItem.Price + "</br>";
            NewObj.Price = dataItem.Price;
            NewArr[indexOfDup] = NewObj; //but how to know index?
        }else{
            NewArr.push(data[index]);
        }

});

Но это неправильно, так как правильно написать синтаксис?

Ответы [ 5 ]

0 голосов
/ 13 сентября 2018

Вот одно решение, использующее reduce. Сначала я создал структуру карты, используя массивы для свойств, которые имеют несколько значений. Затем я использую организованную структуру, чтобы отформатировать данные так, как вы хотите:

var data = [{
  Country_Code: "RU",
  Country: "Russia",
  Provider: "Shell1",
  Price: "0.123"
}, {
  Country_Code: "EN",
  Country: "Russia",
  Provider: "Shell",
  Price: "0.76856"
}, {
  Country_Code: "RO",
  Country: "Russia",
  Provider: "Shell",
  Price: "0.563"
}, {
  Country_Code: "RU",
  Country: "Russia",
  Provider: "Shell2",
  Price: "0.90890"
}, {
  Country_Code: "RU",
  Country: "Russia",
  Provider: "Shell3",
  Price: "0.90"
}];

//First, make a map structure for organization
var map = data.reduce((map, el) => {
  let provider = [];
  let price = [];
  if (map[el.Country_Code]) {
    provider = map[el.Country_Code].Provider;
    price = map[el.Country_Code].Price;
  }
  provider.push(el.Provider);
  price.push(el.Price);

  map[el.Country_Code] = {
    Country_Code: el.Country_Code,
    Country: el.Country,
    Provider: provider,
    Price: price
  }
  return map;
}, {});

//Use the data map to display the data however you want
var formatted = Object.values(map).map((el) => {
  return {
    Country_Code: el.Country_Code,
    Country: el.Country,
    Provider: el.Provider.reduce((str, providerEl, idx) => {
      return str += `${providerEl} - ${el.Price[idx]}</br>`;
    }, ''),
    Price: el.Price[0] //this doesnt make sense IMO, but will leave it since that's how you asked for the data
  }
});

console.log(Object.values(formatted));
//{Country_Code: "RU", Country: "Russia", Provider: "Shell1 - 0.123</br>Shell2 - 0.90890</br>Shell3 - 0.90", Price: "0.123"}
0 голосов
/ 13 сентября 2018

Есть много способов ее решить.Вот мой маленький вклад, предложенный мной алгоритм не использует алгоритм поиска.Таким образом, он может работать относительно быстро для больших массивов.

var myArray = [{Country_Code: "RU", Country: "Russia", Provider: "Shell1", Price: "0.123"},
{Country_Code: "EN", Country: "Russia", Provider: "Shell", Price: "0.76856"},
{Country_Code: "RO", Country: "Russia", Provider: "Shell", Price: "0.563"},
{Country_Code: "RU", Country: "Russia", Provider: "Shell2", Price: "0.90890"},
{Country_Code: "RU", Country: "Russia", Provider: "Shell3", Price: "0.90"}];


var groupByCountryCode = function(xs, key) {
  return xs.reduce(function(rv, x) {
    if(rv[x[key]]){
      // It has found more than one instance

      rv[x[key]][0].Provider += " " + x.Provider;
    }else{
      rv[x[key]] = [];
      rv[x[key]].push(x);
    }
    return rv;
  }, {});
};

var grouppedElementsByKey = groupByCountryCode(myArray,"Country_Code");

var grouppedArray =   Object.keys(grouppedElementsByKey).map(function(key){
  return grouppedElementsByKey[key][0];
});


console.log(grouppedArray);

Окончательный результат будет таким, как вы просили.

0 голосов
/ 13 сентября 2018

Вам понадобится array.reduce. Вернуть массив с помощью array.reduce. В этом массиве проверьте, существует ли уже объект, в котором существует код страны, используя findIndex. Если он существует, обновите значение свойства

let x = [{
    Country_Code: "RU",
    Country: "Russia",
    Provider: "Shell1",
    Price: "0.123"
  },
  {
    Country_Code: "EN",
    Country: "Russia",
    Provider: "Shell",
    Price: "0.76856"
  },
  {
    Country_Code: "RO",
    Country: "Russia",
    Provider: "Shell",
    Price: "0.563"
  },
  {
    Country_Code: "RU",
    Country: "Russia",
    Provider: "Shell2",
    Price: "0.90890"
  },
  {
    Country_Code: "RU",
    Country: "Russia",
    Provider: "Shell3",
    Price: "0.90"
  }
]


let m = x.reduce(function(acc, curr) {
  let findIndex = acc.findIndex((item) => {
    return item['Country_Code'] === curr['Country_Code']
  });
  if (findIndex === -1) {
    acc.push(curr)
  } else {
    acc[findIndex].Provider = acc[findIndex].Provider + ' - ' + acc[findIndex].Price + '<br/>' + curr.Provider + ' - ' + curr.Price
  }

  return acc;


}, []);

console.log(m)
0 голосов
/ 13 сентября 2018
'use strict';

const data = [
  {Country_Code: "RU", Country: "Russia", Provider: "Shell1", Price: "0.123"},
  {Country_Code: "EN", Country: "Russia", Provider: "Shell", Price: "0.76856"},
  {Country_Code: "RO", Country: "Russia", Provider: "Shell", Price: "0.563"},
  {Country_Code: "RU", Country: "Russia", Provider: "Shell2", Price: "0.90890"},
  {Country_Code: "RU", Country: "Russia", Provider: "Shell3", Price: "0.90"}
];

// create a hashmap by country code
const dataPerCountry = data.reduce((dataCountry, currentValue) => {
  const item = {  }
  if (dataCountry[currentValue.Country_Code]) {
    dataCountry[currentValue.Country_Code].Provider.push(currentValue.Provider);
  } else {
    dataCountry[currentValue.Country_Code] = { 
      ...currentValue,
      Provider: [currentValue.Provider],
    };
  }

  return dataCountry;
}, {});

/** 
 * Transform the hasmap into an array of objects used by the view,
 * also applying the transformation to concat the Providers
 **/
const reducedCountriesVO = Object.keys(dataPerCountry).map((countryCode) => {
  const dataCountry = { ...dataPerCountry[countryCode] };

  dataCountry.Provider = dataCountry.Provider.join('<br>-');

  return dataCountry;
});

console.log(reducedCountriesVO);
0 голосов
/ 13 сентября 2018

Вы можете использовать array.indexOf(someValue) свойство здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...