Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle duplicate keys? #8

Closed
Professor-Heavy opened this issue Apr 9, 2019 · 6 comments
Closed

How to handle duplicate keys? #8

Professor-Heavy opened this issue Apr 9, 2019 · 6 comments

Comments

@Professor-Heavy
Copy link

Professor-Heavy commented Apr 9, 2019

Sorry for the silly question, I'm new to this entire C# scene, and I'm using this parser for a project. As a result, I'm probably being a complete and total idiot and that my issue is common C# knowledge.

If two keys with the same name exist in the same object, they're both used in that object but have the same value. In the VDF formatted file that I'm using, though, they both have different values.

In other words, is it possible to access these values like a numeric array to avoid this issue? Or is there anything else in this parser that lets me do this?

@shravan2x
Copy link
Owner

No, your question is definitely a good one. I'll include this in the FAQ at some point.

In general, you cannot access values of duplicate keys in the same way you would a dictionary, which VObject inherits from. So when you access a property by its key name, you always get the first corresponding value.

But there is something you can do. VObject maintains a copy of every child VProperty, which you can access by calling Children(). Assume you have VDF data like:

"root"
{
    "key1" "value1"
    "key2" "value2"
    "key1" "value3"
}

To access the last value of "key1", just do:

VProperty root = VdfConvert.Deserialize(vdf);
Console.WriteLine(root.Value["key1"]); // Prints 'value1'
Console.WriteLine(root.Value["key2"]); // Prints 'value2'
Console.WriteLine(root.Value.Children().Last(x => x.Key == "key1").Value); // Prints 'value3'

As an aside, could you tell me where you found the erroneous VDF data you have? Did you find it in the Steam installation directory?

@shravan2x
Copy link
Owner

shravan2x commented Apr 10, 2019

To add to my previous response, if you need an array of values, just do:

VToken[] vals = root.Value.Children().Where(x => x.Key == "key1").Select(x => x.Value).ToArray();

@shravan2x
Copy link
Owner

I'm closing this issue due to inactivity. If you have further questions, feel free to reopen.

@Bluscream
Copy link

Bluscream commented May 16, 2020

If anyone else stumbles across this issue and just wants to treat duplicates differently:

var json = VdfConvert.Deserialize(text).ToJson(new VdfJsonConversionSettings() { ObjectDuplicateKeyHandling = DuplicateKeyHandling.Ignore, ValueDuplicateKeyHandling = DuplicateKeyHandling.Ignore });

@shravan2x
Copy link
Owner

@Bluscream Note that your solution only applies when converting a VObject to a JObject. I believe the author was asking about accessing properties with duplicate keys directly within a VObject.

@ZzZombo
Copy link

ZzZombo commented Nov 21, 2023

There is one misconception about VDF: it's not a dictionary! The best unambiguous way to represent parsed VDF data is to use a list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants