Reputation: 2055
I need find dublicates by country code and join them into one object
Array structure is:
[{...},{...}]
Objects
{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"}
I need get Array of object
[{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"}]
If think must be somethink like
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]);
}
});
But it wrong, so how to write right syntax?
Upvotes: 0
Views: 108
Reputation: 5941
Here is one solution using reduce
. First, I created a map structure using arrays for properties that have multiple values. Then I use the organized structure to format the data to look the way you want:
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"}
Upvotes: 1
Reputation: 970
There are many ways to solve it. Here is my small contribution, the algorithm that I have proposed doesn't use any search algorithm. So, it can perform relative fast for big arrays.
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);
The final output will be like you have requested.
Upvotes: 1
Reputation: 2799
'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);
Upvotes: 1
Reputation: 50291
You will need array.reduce
. Return a array using array.reduce. In this array check if there already exist an object where the country_code exist using findIndex
. If it exist then update the property value
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)
Upvotes: 1