- Home /
Nested foreach and variables in method calls
Is is possible to set up a nested foreach that checks variables in classes in one list vs variables in classes in another list?
I want to see who is the most applicable for an action in my game by checking a characters skills vs all the other characters in the area. Some times a task will require multiple skills so I'm trying to get the best possible applicant for the skill
public class Activity : MonoBehaviour {
public string name {get; set;}
public int duration {get; set;}
public List<string> skillsreq {get; set;}
public List<Character> bestapplicant { get; set;}
public Character bestapplicantfilter (List<Character> applicants)
{
foreach (Character applicant in applicants)
{ int count = 0;
foreach (string skill in skillsreq )
{ count += 1;
if (applicant.skills.skill.name.adjustedamount > bestapplicant[count].skills.skill.name.adjustedamount)
{
bestapplicant = applicant;
}
}
}
}
}
This is my general idea on how this might work. but I don't know if I can search through a list, in a class, in a list by a variable (the skills of a character are set as a list in that character, and the characters are put in a list for organization)
I'm not sure I know exactly what you want to achieve, but from your explanation: Yes that is possible. I think you just want to save the Character
with the highest value for its adjustedamount
value. Is that right?
In that case, keep the loops the same and use another variable highestAmount
against which you compare the values.
I want to save the character with the best combo of skills for the action. Each character has a list of skills in it's class that this needs to sort through and then deter$$anonymous$$e who is best qualified.
It's like:
public class Character
{
//some other character stuff
public List<Skills> skills {get; set;}
}
and each skill:
public class Skills
{
// info about skills
string name;
int adjustedamount;
}
So I want to go into the characters skill list, then look through it for the named skill, accessing classes with in classes i guess.
What do you mean by "adjustedamount" in the Skills class? I'm guessing from your description of the problem you are trying to solve that "adjustedamount" is how much use a particular skill is for carrying out a specific action and so the same skill should have different adjustedamount values for different actions?
Answer by Teravisor · Mar 07, 2016 at 11:50 PM
Yes, you can search through list. For example, you can use method Find with lambda expression as parameter your if statement should look like:
if (applicant.skills.Find(sk=>sk.name==skill).adjustedamount > bestapplicant[count].skills.Find(sk=>sk.name==skill).adjustedamount)
Here sk=>sk.name==skill
is lambda expression. It's same as method that would take parameter sk
do sk.name==skill
comparison on it and return result of that comparison.
Be warned that if Find method doesn't find anything, it will return null and the line I wrote will throw NullReferenceException. If you are not sure that those skills will be present in those lists, do Find(...) calls before if statement and check if their result is not null.
Also you might need to confirm access level of Skills.name field (depending on where it's declared it might need to be public).
Also, you might consider using Dictionary or any other collection that allows you to get specific value without searching for it instead of List if you'll ever run into performance troubles.
Answer by PingwinGames · Mar 08, 2016 at 01:20 PM
Try breaking problems like this down into smaller chunks, e.g. just think about how you could return a score for a single character:
public int GetCharacterSkillPoints(List<string> skillsRequired, Character character)
{
int result = 0;
foreach( Skill skill in character.skills )
{
if ( skillsRequired.Contains(skill.name) )
{
result += skill.adjustedamount;
}
}
return result;
}
Now you can put that function into your BestApplicantFilter function:
public Character bestapplicantfilter (List<Character> applicants)
{
Character bestApplicant = null;
int bestScore = -1;
foreach (Character applicant in applicants)
{
int score = GetCharacterSkillPoints(skillsreq,applicant);
if ( score > bestScore )
{
bestScore = score;
bestApplicant = applicant;
}
}
return bestApplicant;
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Methods list in inspector 0 Answers
How to check if a value exists in an array (C#) 3 Answers
Make Lists within a List 0 Answers