Remove duplicates from a sorted ArrayList array while retaining some elements from duplicates

Well, at first I thought it would be pretty simple. But I can’t come up with an effective way to solve this problem. I decided that this can be done, but it is not very elegant. I have an ArrayList. Contacts is a VO class that has several members - name, regions, identifier. There are duplicates in ArrayList because different regions appear several times. The list is sorted by identifier. Here is an example:

Intro 0 - Name: John Smith; Region: N; ID: 1 | Record 1 - Name: John Smith; Region: MW; ID: 1 | Record 2 - Name: John Smith; Region: S; ID: 1 | Record 3 - Name: Jane Doe; Region: NULL; ID: 2 | Record 4 - Name: Jack Black; Region: N; ID: 3 | Record 6 - Name: Jack Black; Region: MW; ID: 3 | Record 7 - Name: Joe Don; Region: NE; ID: 4

I want to convert the list below by combining repeating areas together for a single ID. Therefore, in the final list there should be only 4 separate elements with combined regions.

Thus, the result should look like this: -

Intro 0 - Name: John Smith; Region: N, MW, S; ID: 1 | Record 1 - Name: Jane Doe; Region: NULL; ID: 2 | Record 2 - Name: Jack Black; Region: N, MW; ID: 3 | Record 3 - Name: Joe Don; Region: NE; ID: 4

What are your thoughts on the best way to solve this problem? I am not looking for actual code, but ideas or tips to find the best way to do this.

Thank you for your time!!!

+3
source share
4 answers

You can repeat them when dropping them (and merging duplicates) in TreeMap. Then create a list from the sorted representation of the TreeMap values.

In the code example, I assume that you have an Entry class with id, name, and regions fields, this last one is an instance of List of Region. This can easily be changed to Set, and Region to Strings, or whatever you use. The sample copies the records before pasting them into the card, as they will be changed when combined with other records.

SortedMap<Integer, Entry> mergedEntriesMap = new TreeMap<Integer, Entry>();
for (Entry e : entries) {
  if (mergedEntriesMap.contains(e.id)) {
    Entry m = mergedEntriesMap.get(e);
    m.regions.addAll(e.regions);
  } else {
    Entry m = new Entry();
    // copy the entry to keep the original array clean
    m.id = e.id;
    m.name = e.name;
    m.regions = new ArrayList<Region>(e.regions);
    mergedEntriesMap.put(m.id, m);
  }
}

List<Entry> mergedEntries = new ArrayList<Entry>(mergedEntriesMap.values());
+2
source

? , , , , , , . sql

SELECT      Id, [Name], Regions = replace
            ((SELECT Region AS [data()]
            FROM RegionTable
            WHERE  Id = u.Id
            ORDER BY Region FOR xml path('')), ' ', ', ')
FROM        [User] u
WHERE       Id IS NOT NULL
GROUP BY Id, [Name]
+2

, , . Pair<K,V> (first, second), K, (.. (k1,v1) (k1,v2), (k1,v1) .

(k,v1),(k,v2),(k,v3) (k,[v1,v2,v3]).

List<Pair<K,V>> in;
List<Pair<K,List<V>>> out = [ ];

Pair<K,V> lastP = SENTINEL_PAIR; // lastP.first matches nothing
Pair<K,List<V>> lastGroup;

for (Pair<K,V> p : in) {
  if (p.first == lastP.first) {  // same group as last
    lastGroup.second.add(p.second);
  } else {                       // start a new group
    lastGroup = (p.first, [ p.second ]);
    out.add(lastGroup);
  }
  lastP = p;
}

K - , V - . O(N).

+1

Have you looked at google Multimap? It is largely created for this type of data structure in which there is a key that maps to Collectionelements. Therefore, in this case, the name Stringwill be displayed in the Collectionobjects Region.

Multimap<String, Region> names = HashMultimap.create();
for (Entry entry : entries) {
    names.put(entry.getName(), entry.getRegion());
}
// Now u can get the collection of regions by name
Collection<Region> johnsRegions = names.get("John Smith");
0
source

Source: https://habr.com/ru/post/1736016/


All Articles