I have LINQ logic that collects regex parsed data into a dynamically-created dictionary. The issue I am facing is accessing the data in the dictionary (Info
).
Regex
.Matches(text, pattern,
RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture)
.OfType<Match>()
.Select(mt => new
{
Info = mt.Groups["ADKey"].Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.Zip(mt.Groups["ADValue"].Captures.OfType<Capture>().Select(cp => cp.Value),
(k, v) => new { key = k, value = v })
.ToDictionary(cp => cp.key, cp => cp.value),
Nodes = mt.Groups["Key"].Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.Zip(mt.Groups["Value"].Captures.OfType<Capture>().Select(cp => cp.Value),
(k, v) => new { key = k, value = v })
.ToDictionary(cp => cp.key, cp => cp.value),
});
List<string> myInfo = new List<string>();
myInfo = Info.Keys.ToList();
When I try to access the dictionary(info), while converting to list, I get the error that "Info" is inaccessible due to its protection level. How do I fix that?
You are currently creating a list of anonymous types which have a single property, Info
, that is a Dictionary<string, string>
. You don't appear to be capturing the result in a variable. Then you try to access Info
as if it were a single object outside of the RegEx
query. Those two Info
reference different things.
The first suggestion I have for you is to change your code like this:
IEnumerable<Dictionary<string, string>> query =
Regex
.Matches(
text,
pattern,
RegexOptions.IgnorePatternWhitespace
| RegexOptions.ExplicitCapture)
.OfType<Match>()
.Select(mt => mt.Groups["Key"].Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.Zip(
mt.Groups["Value"].Captures
.OfType<Capture>()
.Select(cp => cp.Value),
(k, v) => new
{
key = k,
value = v
})
.ToDictionary(cp => cp.key, cp => cp.value));
Now, I don't believe you want a IEnumerable<Dictionary<string, string>>
, because on your next two lines you seem to want the to pull the keys straight out of the results.
It appears that you might want this:
Dictionary<string, string> query =
Regex
.Matches(text, pattern,
RegexOptions.IgnorePatternWhitespace
| RegexOptions.ExplicitCapture)
.OfType<Match>()
.SelectMany(mt => mt.Groups["Key"].Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.Zip(
mt.Groups["Value"].Captures
.OfType<Capture>()
.Select(cp => cp.Value),
(k, v) => new
{
key = k,
value = v
}))
.ToDictionary(cp => cp.key, cp => cp.value);
But I suspect this will have key collisions.
I think you probably want something like this:
Match match = Regex.Match(text, pattern,
RegexOptions.IgnorePatternWhitespace
| RegexOptions.ExplicitCapture);
Dictionary<string, string> result =
match
.Groups["Key"]
.Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.Zip(
match.Groups["Value"].Captures
.OfType<Capture>()
.Select(cp => cp.Value),
(k, v) => new
{
key = k,
value = v
})
.ToDictionary(cp => cp.key, cp => cp.value);
Then you can do this:
List<string> myInfo = result.Keys.ToList();
Given your updated question it seems to me you might want this:
Match match =
Regex.Match(text, pattern,
RegexOptions.IgnorePatternWhitespace
| RegexOptions.ExplicitCapture);
var result = new
{
Info = match.Groups["ADKey"].Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.Zip(match.Groups["ADValue"].Captures.OfType<Capture>().Select(cp => cp.Value),
(k, v) => new { key = k, value = v })
.ToDictionary(cp => cp.key, cp => cp.value),
Nodes = match.Groups["Key"].Captures
.OfType<Capture>()
.Select(cp => cp.Value)
.Zip(match.Groups["Value"].Captures.OfType<Capture>().Select(cp => cp.Value),
(k, v) => new { key = k, value = v })
.ToDictionary(cp => cp.key, cp => cp.value),
};
List<string> myInfo = result.Info.Keys.ToList();