Reputation:
I have this JSON file that stores Dokkan Passives for my Discord Bot for people to use and I recently added a Slash command where the user can Delete a passive based on the name they pass through it. If the name matches an entry in the JSON file then it can go ahead and delete the whole member from the JSON file, this is what I'm trying to do.
This is what part of my JSON File looks like
{
"userPassiveStorage": "Storage for user created passives using /passivecreator",
"members": [
{
"membersJSONList": [],
"Error": null,
"UserName": "𝕤𝕒𝕞.𝕛𝕖𝕤𝕦𝕤𝟠",
"PassiveName": "TestTUR",
"Rarity": "TUR",
"UnitHP": 10000,
"UnitATK": 19234,
"UnitDEF": 14235,
"UnitLeaderName": "A TUR Passive",
"UnitLeaderSkill": 200,
"UnitPassiveATK": 250,
"UnitPassiveDEF": 150,
"DmgReduction": 30,
"Support": 30,
"Links": "No active Links"
},
{
"membersJSONList": [],
"Error": null,
"UserName": "𝕤𝕒𝕞.𝕛𝕖𝕤𝕦𝕤𝟠",
"PassiveName": "TEQ Jiren",
"Rarity": "LR",
"UnitHP": 20863,
"UnitATK": 21525,
"UnitDEF": 14338,
"UnitLeaderName": "Universe 11",
"UnitLeaderSkill": 170,
"UnitPassiveATK": 200,
"UnitPassiveDEF": 200,
"DmgReduction": 30,
"Support": 0,
"Links": "No active Links"
}
]
}
I will explain what I'm trying to get this command to do
This is my current method within a class where I can Load passives & hopefully Delete passives at the same time, it takes in a parameter object which loads in the already searched passive if Step 4 was successful
public bool DeleteSpecificPassive(DokkanUserPassiveBuilder classObj)
{
try
{
//var path = @"C:\Users\samue\Documents\Bot\bin\Debug\UserPassivesStorage.json";
var path = @"D:\Visual Studio Projects\DiscordBotTest\bin\Debug\UserPassivesStorage.json";
var json = File.ReadAllText(path);
var jsonObj = JObject.Parse(json);
var members = jsonObj["members"].ToObject<List<DokkanUserPassiveBuilder>>();
if (members.Contains(classObj))
{
members.Remove(classObj);
jsonObj["members"] = JArray.FromObject(members);
File.WriteAllText(path, jsonObj.ToString());
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
Error = ex.ToString();
return false;
}
}
For some reason, when I type in a correct passive name like "TEQ Jiren", even though it exists in the list, the if statement comparing the user input with the JSON file doesn't work and goes to the else block instead. So how can I get it so that the user input and the member in the class are compared and if it exists in the List then delete it and rewrite the JSON file?
If you want to view the full class for the bigger picture the Discord Bot is in my GitHub repo where I carry out these commands ->
[DokkanUserPassivesBuilder.cs] (https://github.com/samjesus8/CoolerDiscordBot/blob/master/Builders/DokkanUserPassiveBuilder.cs)
Upvotes: 0
Views: 104
Reputation: 115
Why it may not work:
In question you say that user passes the name of the passive they are trying to delete, but in code you pass whole object as argument (then are other fields empty?).
As I see in code from GitHub you have provided, you are trying to compare objects of different classes, this will not work unless you have overridden Equals method.
As I know objects by default are compared by reference, so even if you have two identical objects but they do not point to same object in heap, they considered as different objects.
How to fix this:
Consider using @vernou answer, it should be faster.
Using Linq to find object with provided PassiveName:
var found = members.FirstOrDefault(m => m.PassiveName == classObj.PassiveName);
if (found != null)
{
members.Remove(found);
jsonObj["members"] = JArray.FromObject(members);
File.WriteAllText(path, jsonObj.ToString());
return true;
}
else
{
return false;
}
Upvotes: 1
Reputation: 7590
By defaut, the method Contains
search by reference.
In the OP code :
var members = jsonObj["members"].ToObject<List<DokkanUserPassiveBuilder>>();
This generate new instances, distinct of classObj
.
A solution, it's to search the index from a predicate and remove the element at the found index like :
var members = jsonObj["members"].ToObject<List<DokkanUserPassiveBuilder>>();
var indexToRemove = members.FindIndex(m => m.PassiveName == classObj.PassiveName)
if (indexToRemove != -1)
{
members.RemoveAt(indexToRemove);
jsonObj["members"] = JArray.FromObject(members);
File.WriteAllText(path, jsonObj.ToString());
return true;
}
Upvotes: 1