0

I have a lstSubs List<KeyValuePair<string, string> which contain value

  • FNAME, "ABC"
  • LNAME ,"XYZ"
  • VAR001, "VAR002"
  • VAR002 , "ActualValueforVAR001"
  • VAR003, "VAR004"
  • VAR004 , "VAR005"
  • VAR005, "ActualValueforVAR003"

I have a String like envelop "Hello [FNAME] [LNAME] you have created a request for [VAR001] which got assigned to [VAR003]"

 var regex = new Regex(@"\[(.*?)\]");
                    var matches = regex.Matches(envelop.ToString());
                    foreach (Match match in matches) 
                    {  
                       columnValue = linq to get the value from the list based on key;
                       envelop.Replace(match.Value, columnValue);
                    }

in this, The straight Key,Value pairs are easy to get via Linq but I am getting tough time to fetch the complex values which are nested in terms of connected Key, Value.


is there any way in LINQ or have to go with a loop. Expected Output : Hello ABC XYZ you have created a request for ActualValueforVAR001 which got assigned to ActualValueforVAR003

Thanks, PS. The code is not complete. it's a part of entire code edited with an intention to make it concise to issue

Edited: some of my text was not visible due to formatting. They Dictionary values are nested as I am creating them based on some conditions in which they got configured

Amit Singh
  • 344
  • 3
  • 18

1 Answers1

1

First, let's turn initial List<T> into a Dictionary<K, V>:

  List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>() {
    new KeyValuePair<string, string>("FNAME", "ABC"),
    new KeyValuePair<string, string>("LNAME", "XYZ"),
    new KeyValuePair<string, string>("VAR001", "VAR002"),
    new KeyValuePair<string, string>("VAR002", "ActualValueforVAR001"),
    new KeyValuePair<string, string>("VAR003", "VAR004"),
    new KeyValuePair<string, string>("VAR004", "VAR005"),
    new KeyValuePair<string, string>("VAR005", "ActualValueforVAR003"),
  };

  Dictionary<string, string> dict = list.ToDictionary(
    pair => pair.Key, 
    pair => pair.Value,
    StringComparer.OrdinalIgnoreCase); // Comment out if should be case sensitive

  // Some values can be nested
  while (true) {
    bool nestedFound = false;

    foreach (var pair in dict.ToList()) {
      if (dict.TryGetValue(pair.Value, out var newValue)) {
        dict[pair.Key] = newValue;
        nestedFound = true;
      }
    }

    if (!nestedFound)
      break;
  }

Then for a given envelop

  string envelop = 
    @"Hello [FNAME] [LNAME] you have created a request for [VAR001] which got assigned to [VAR003]";

you can put a simple Regex.Replace:

  string result = Regex
    .Replace(envelop,
           @"\[[A-Za-z0-9]+\]",
             m => dict.TryGetValue(m.Value.Trim('[', ']'), out var value) ? value : "???");

  Console.Write(result);

Outcome:

  Hello ABC XYZ you have created a request for ActualValueforVAR001 which got assigned to ActualValueforVAR003
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • sorry for the trouble. but I think I wasn't able to put that up clearly. I need to traverse to find the ActualValue via keys.Thanks – Amit Singh Oct 11 '19 at 09:23
  • @Amit Singh: I see; you have *nested* values; need some loop after initial dictionary creation; I've edited the answer – Dmitry Bychenko Oct 11 '19 at 10:12
  • awesome, I actually did something the same, but your code is very clean. would be using this. Thanks for the help :) – Amit Singh Oct 11 '19 at 10:25