Hassan
Hassan

Reputation: 5430

Sort data within string value

A string that contains date and integer in specific format: MM/dd/yyyy (Number)

string strData = "01/23/2017 (5); 01/16/2017 (2);01/24/2017 (6);01/16/2017 (5);01/23/2017 (10)";

Based on above I want following:

  1. Add Number if date is similar
  2. Sorting should be based on date i.e. Ascending

Expected Output:

strData = "01/16/2017 (7);01/23/2017 (15);01/24/2017 (6)";    

I know it is possible, if we split on the basis of semicolon and then traverse values using 'for-loop'.

But please suggest me linq solution.

Upvotes: 1

Views: 198

Answers (2)

Najkin
Najkin

Reputation: 932

This should work:

var elems = strData.Split(';') // First, split on semicolon
  .Select(s => s.Trim().Split(' ')) // then remove the extra space at the end of each element, and split again on the space
  .Select(s => new { d = DateTime.ParseExact(s[0], "MM/dd/yyyy", CultureInfo.InvariantCulture), n = int.Parse(s[1].Replace("(", "").Replace(")", "")) }) // here, we create a temp object containing the parsed date and the value
  .GroupBy(o => o.d) // group by date
  .OrderBy(g => g.Key) // then sort
  .Select(g => $"{g.Key:MM'/'dd'/'yyyy} ({g.Sum(a => a.n)})"); // and finally build the resulting string

You can then build the final string with:

string.Join(";", elems);

This answer uses C# 6 interpolated strings. If using an older version of the language, replace $"{g.Key:MM'/'dd'/'yyyy} ({g.Sum(a => a.n)})" by string.Format("{0:MM'/'dd'/'yyyy} ({1})", g.Key, g.Sum(a => a.n))

Upvotes: 5

fubo
fubo

Reputation: 45947

Here is another approach

string strData = "01/23/2017 (5); 01/16/2017 (2);01/24/2017 (6);01/16/2017 (5);01/23/2017 (10)";
string result = string.Join(";", strData.Split(';')
          .Select(x => new { 
              Date = DateTime.ParseExact(x.Trim().Split()[0], "MM/dd/yyyy", CultureInfo.InvariantCulture), 
              Count = int.Parse(x.Trim().Split()[1].Trim('(', ')')) })
          .GroupBy(x => x.Date)
          .OrderBy(x => x.Key)
          .Select(x => x.Key.ToString("MM/dd/yyyy") + " (" + x.Sum(y => y.Count) + ")")); 

Upvotes: 2

Related Questions