Randel Ramirez
Randel Ramirez

Reputation: 3761

How to check for duplicates in an array and then do something with their values?

I have an array for example("1:2","5:90","7:12",1:70,"29:60") Wherein ID and Qty are separated by a ':' (colon), what I want to do is when there's a duplicate of IDs the program will add the qty and return the new set of arrays so in the example it will become ("1:72","5:90","7:12","29:60").

Ex.2 ("1:2","5:90","7:12","1:70","29:60","1:5") becomes ("1:77","5:90","7:12","29:60").

I want to solve it without using linq.

Upvotes: 0

Views: 359

Answers (6)

jason
jason

Reputation: 241641

var foo = array.Select(s => s.Split(':'))
               .GroupBy(x => x[0])
               .Select(g => 
                    String.Format(
                        "{0}:{1}",
                        g.Key,
                        g.Sum(x => Int32.Parse(x[1]))
                    )
               )
               .ToArray();

Note, it's not necessary to parse the "keys," only the values.

Without LINQ:

var dictionary = new Dictionary<string, int>();
foreach (var group in array) {
    var fields = group.Split(':');
    if (!dictionary.ContainsKey(fields[0])) {
        dictionary.Add(fields[0], 0);
    }
    dictionary[fields[0]] += Int32.Parse(fields[1]);
}
string[] foo = new string[dictionary.Count];
int index = 0;
foreach (var kvp in dictionary) {
    foo[index++] = String.Format("{0}:{1}", kvp.Key, kvp.Value);
}

Upvotes: 3

Alex Mendez
Alex Mendez

Reputation: 5150

try this:

List<string> items = new List<string>(new string[] { "1:2", "5:90", "7:12", "1:70", "29:60" });
Dictionary<string, int> dictionary = new Dictionary<string, int>();

foreach (string item in items)
{
    string[] data = item.Split(':');
    string key = data[0];

    if (!dictionary.ContainsKey(data[0]))
    {
        int value = dictionary[data[0]];
        dictionary[key] += int.Parse(data[1]);
    }
}

//Used dictionary values here

Upvotes: 1

penartur
penartur

Reputation: 9912

If you want it without LINQ...

var totalQuantities = new Dictionary<int, int>();
foreach(var raw in sourceArr) {
    var splitted = raw.Split(':');
    int id = int.Parse(splitted[0]);
    int qty = int.Parse(splitted[1]);
    if(!totalQuantities.ContainsKey(id)) {
        totalQuantities[id] = 0;
    }
    totalQuantities[id] += qty;
}

var result = new string[totalQuantities.Count];
int i=0;
foreach(var kvp in totalQuantities) {
    result[i] = string.Format("{0}:{1}", kvp.Key, kvp.Value);
    i++;
}

Upvotes: 1

CodesInChaos
CodesInChaos

Reputation: 108810

var input=new string[]{"1:2","5:90","7:12","1:70","29:60","1:5"};
var result=input
             .Select(s=>s.Split(':'))
             .Select(x=>x.Select(s=>int.Parse(s)).ToArray())
             .GroupBy(x=>x[0])
             .Select(g=>g.Key+":"+g.Sum(x=>x[1]));

I was too lazy to specify the culture everywhere. You probably want to do that before putting it into production, or it will fail for cultures with unusual integer representations.

var totals=new Dictionary<int,int>
foreach(string s in input)
{
  string[] parts=s.Split(':');
  int id=int.Parse(parts[0]);
  int quantity=int.Parse(parts[0]);
  int totalQuantity;
  if(!totals.TryGetValue(id,out totalQuantity))
      totalQuantity=0;//Yes I know this is redundant
  totalQuanity+=quantity;
  totals[id]=totalQuantity;
}
var result=new List<string>();
foreach(var pair in totals)
{
  result.Add(pair.Key+":"+pair.Value);
}

Upvotes: 1

iefpw
iefpw

Reputation: 7042

You have to do this manually. Loop through each list, check the ID for each element. Put it in a Dictionary<int, int>, Dictionary<id, qt>. If the dictionary contains the id, add it to the value.

  1. Loop, add, check using Dictionary class.

Upvotes: 2

penartur
penartur

Reputation: 9912

(
    from raw in arr
        let splitted = raw.Split(':')
        let id = int.Parse(splitted[0])
        let qty = int.Parse(splitted[1])
        let data = new { id, qty }
        group data by data.id into grp
            let totalQty = grp.Sum(val => val.qty)
            let newStr = string.Format("{0}:{1}", grp.Key, totalQty
            select newStr
)
.ToArray()

Note that the code may contain accidental errors, as it was written in notepad.

Upvotes: 1

Related Questions