Combining duplicate objects in a JavaScript array

I am looking to identify duplicates by country code and merge them into a single object

The 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 want to get an array of objects like this

[{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 I think the approach should be something 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; 
        }else{
            NewArr.push(data[index]);
        }

});

This syntax is incorrect, so how can I correct it?

Answer №1

When tackling this issue, I approached it from a unique angle. My solution involves an algorithm that operates without the need for any search algorithms. This approach allows it to efficiently handle large 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 end result will align with your original request.

Answer №2

To achieve this task, you can utilize the array.reduce method. The idea is to iterate through an array using array.reduce, and for each object in the array, check if there is already an object with a matching country code using findIndex. If a matching object is found, update the property value accordingly.

let 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"
  }
]

let result = data.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(result)

Answer №3

'use strict';

const info = [
  {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"}
];

// convert the data into a hashmap based on country code
const countryDataMap = info.reduce((dataByCountry, current) => {
  const itemObj = {};
  if (dataByCountry[current.Country_Code]) {
    dataByCountry[current.Country_Code].Provider.push(current.Provider);
  } else {
    dataByCountry[current.Country_Code] = { 
      ...current,
      Provider: [current.Provider],
    };
  }

  return dataByCountry;
}, {});

/** 
 * Convert the hashmap back to an array of objects for display purposes,
 * also concatenating the Providers.
 **/
const processedCountriesInfo = Object.keys(countryDataMap).map((code) => {
  const countryData = { ...countryDataMap[code] };

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

  return countryData;
});

console.log(processedCountriesInfo);

Answer №4

Below is a solution utilizing the reduce method. Initially, I structured a map using arrays for properties with multiple values. Subsequently, I used this organized structure to format the data according to your requirements:

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"
}];

//Creating 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;
}, {});

//Utilizing the data map to present the data in desired format
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]
  }
});

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"}

Answer №5

A convenient way to find the index of a specific value in an array is by using the array.indexOf(someValue) method.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

choose multiple elements from an array simultaneously

Looking for help with a basic Array question and seeking the most effective solution. The scenario involves having an array: var pathArr = [element1, element2, element3, element4, element5, element6] If I want to select multiple elements from this array ...

Releasing the mouse button after dragging successfully without the use of any libraries

I have implemented a pure CSS snap scroll feature and now I need to determine the position of an element in relation to the viewport once the user stops dragging. However, I prefer not to rely on any complex libraries as I do not require any actual movemen ...

What could be causing a problem with the select query in SQLite for iOS using PhoneGap

Could someone please assist me with retrieving values from a database? Here is my code: <script type="text/javascript" charset="utf-8"> // Wait for Cordova to load document.addEventListener("deviceready", onDeviceReady, false); ...

How to filter an array in Angular 4 without the need for creating a new array and then displaying the filtered results within the same

In my collection of students, I have their names paired with their academic outcomes. studentResults = [ {name: 'Adam', result : 'Passed'}, {name: 'Alan', result : 'Failed'}, {name : 'Sandy', result : &ap ...

Guide to adding Angular 2 components to various locations in the DOM of a vanilla JavaScript webpage

Scenario: A customer is interested in creating a library of Angular 2 components that offer a technology-agnostic interface to developers. This allows developers to use plain JavaScript without needing knowledge of the internal workings of the library. Th ...

Using Svelte to effectively connect to a specified object within an array

Check out this code snippet: <script> let data = [ {id: 1, first: "x"}, {id: 2, second: "y"} ]; </script> <input type="text" bind:value={data.first}/> If you modify the value in the input field and ...

What is the best way to assign the result of a promise to a variable?

My code includes an async function that retrieves a value async fetchUserName(environment: string, itemName: string, authToken: string): Promise<any> { let result = await this.obtainDeviceName(environment, itemName, authToken); return ...

How can I organize data from A to Z in alphabetical order in React Native when the user chooses the A to Z option from the dropdown menu?

I am working on a screen that can display up to 1000 data retrieved from the API. Here is the image: https://i.sstatic.net/ErbDD.png Now, I have implemented a drop-down box where users can select alphabetically from A to Z. After selecting an alphabetic ...

How can you store a Json Object with nested arrays, including other Json objects, in a single table in an SQL database?

I develop applications using the Spring framework. Below is a snippet of JSON data (an array of JSON objects) that I am working with: [{"id" : 643419352, "status" : "removed_by_user", "url" : "https://www.o ...

Trouble populating array using the .Split method

I am struggling to populate the array "whyWontYouWork" with a value. In the provided example, the value of rangeNames[j] is "$A$1:$A$10". Although the string "group" fills in correctly as "$A$1:$A$10", there is an error message stating, "The name 'why ...

Angular Starter Kit

When starting with Angular.js, there are various boilerplate kits available such as angular-seed, some incorporating requirejs and more. However, many of the options I've come across seem to be outdated. As a newcomer to Angular, I'm wondering if ...

Is there a way to assign an array to a jagged array column in VBA without having to declare the former as Variant?

I have a jagged array containing multiple arrays and I am looking to assign a new array with the values of one of the arrays within the jagged array. For instance: arr1 = jaggedarr(2) With the code above, arr1 will be assigned the values of the 2nd array ...

Leverage IBM Worklight to initiate iOS native code execution upon plugin creation

Currently, I am working on integrating iOS Native code into my Worklight application. I have successfully developed a Cordova plug-in with the following code: HelloWorldPlugin.h #import <Foundation/Foundation.h> #import <Cordova/CDV.h; @interf ...

Exploring Enum properties within an angular js select drop down

I am working with an enum in Java that looks like this: public enum myEnum{ enum1("enumDisplayVal1"), enum2("enumDisplayVal2") myEnum(String displayValue) { this.displayValue = displayValue;} private String displayValue; public String getDisp ...

Is there a way to handle the ajax request only when necessary, instead of processing it every few seconds?

Currently, I am working on an AJAX chat system using PHP, MySQL, JavaScript, and AJAX. I have a piece of code that retrieves all chat messages within a div using AJAX, with the function running every 2 seconds. My issue lies in the fact that the div autom ...

What causes the truncation of the backslash in the string "videos1_visualisation.mp4"?

Check out this example of AngularJS code I've created. The factory contains a list of video sources. var videoPlayer=angular.module('videoPlayer',[]) videoPlayer.controller("videoplayer",["$scope","videolist",function($scope,videolist) ...

I am experiencing an issue with my date filter where it does not display any results when I choose the same date for the start and end dates. Can anyone help me troub

Having an issue with my custom filter pipe in Angular. When I select the same dates in the start and end date, it doesn't display the result even though the record exists for that date. I've noticed that I have to enter a date 1 day before or ea ...

Trapped in the Web of Facebook OAuth

I've been struggling with this issue for a day now and I can't seem to pinpoint where I'm going wrong. I have experience working with JavaScript on the client side and recently started following a book tutorial. However, it appears that Face ...

What is the method for converting this pattern into a JavaScript regex?

This code is functioning properly newRow.replace('[[' + key + ']]', item); I attempted to use regex for the replacement, but it is not working as expected newRow.replace('/\[\[' + key + '\]\]/' ...

Place the outcome of the function into the div element's attribute

As a newcomer to HTML and JavaScript, I recently dove into using 3Dmol.js. Following a tutorial, I was able to create this code snippet that actually works: <script src="http://3Dmol.csb.pitt.edu/build/3Dmol-min.js"></script> <div id="el ...