C# Find Index of a List of Classes - c#

Finding an Index of a Class:
The only way I know to find an index of List is
int index = listEmployee.FindIndex(
delegate(Employee findEmployee)
{
return findEmployee.Name.Equals(findName, StringComparison.Ordinal);
});
I was wondering how to add the option to use
int indexT = listEmployee.FindIndex(r >= r.Name == findName);
Or basically what I'm doing wrong that I can't use it.
class Employee
{
private string _name; private int _idNumber;
private string _deptarment; private string _position;
public Employee()
{
_name = ""; _idNumber = 0; _deptarment = ""; _position = "";
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public int IdNumber
{
get { return _idNumber; }
set { _idNumber = value; }
}
public string Department
{
get { return _deptarment; }
set { _deptarment = value; }
}
public string Position
{
get { return _position; }
set { _position = value; }
}
}

I was wondering how to add the option to use
int indexT = listEmployee.FindIndex(r >= r.Name == findName);
That's fine, apart from the syntax problem at r >= which should be r =>
So this works:
int indexT = listEmployee.FindIndex(r => r.Name == findName);
See: Lambda Expressions

int indexT = listEmployee.FindIndex(r => r.Name == findName);
should work. Perhaps you are missing the using System.Linq referece

Not entirely sure what you're trying to accomplish, but a simple List collection is not going to ensure order or sort, so the index (especially if the collection is going to be expected to change) is not a reliable means of accessing a specific object.
If index / order is important, maybe look at a different collection type, such as the Sorted list: http://msdn.microsoft.com/en-us/library/system.collections.sortedlist.aspx
If you're just trying to find a specific object, you can use Linq and just go something like:
listEmployee.Where( r => r.Name == findName );

Related

How to set the Value variable of this custom Odin Inspector class

I know, the title is bad, but I couldn't think if a better one. The question is very specific.
Ok, so I'm using a class in my game identical to Odin Inspector's example RPG Skills classes. But it's set up in a way I don't quite understand and I can't work out how to set the value (I can get it, and there is a setter, so it's possible to set too). Also, all the skill classes/structs/etc are in the same .cs file.
The SkillList function I use to get the Value:
(I get it with skills[Strength].Value; in other classes)
public int this[SkillType type]
{
get
{
for (int i = 0; i < this.skills.Count; i++)
{
if (this.skills[i].Type == type)
return this.skills[i].Value;
}
return 0;
}
set
{
for (int i = 0; i < this.skills.Count; i++)
{
if (this.skills[i].Type == type)
{
var val = this.skills[i];
val.Value = value;
this.skills[i] = val;
return;
}
}
this.skills.Add(new SkillValue(type, value));
}
}
SkillValue struct:
[Serializable]
public struct SkillValue : IEquatable<SkillValue>
{
public SkillType Type;
public int Value;
public SkillValue(SkillType type, int value)
{
this.Type = type;
this.Value = value;
}
public SkillValue(SkillType type)
{
this.Type = type;
this.Value = 0;
}
public bool Equals(SkillValue other)
{ return this.Type == other.Type && this.Value == other.Value; }
}
SkillType enum:
public enum SkillType
{
Science,
Technology,
Arts,
Language,
}
I've tried:
skills[Science].Value = 10;
skills[Science] = new SkillValue(Science, 10);
skills[Science, 10]; (using a new function made by me)
skills[Science](10);
skills[Science].Value(10);
skills[Science] = 10;
But none work, and I'm just guessing randomly now.
How can I set the value?
Thanks
The solution:
character.skills[Rorschach.Character.Skills.SkillType.Science] = value;
Your property is of type int and expects a key of type SkillType so it should probably be
SkillList skills;
skills[SkillType.Science] = 10;
actually also
I get it with skills[Strength].Value;
seems odd with the code you provided. As said the property returns an int which has no property Value so it should actually be
int x = skills[SkillType.Strength];
Now knowing the full implementation code and your actual usage:
public SkillList skills;
...
public int Science
{
get { return this.Character.skills[Science].Value; }
set { this.Character.skills[Science].Value(10); }
}
ATTENTION!
What you did here by accident is using the other property
public SkillValue this[int index]
{
get { return this.skills[index]; }
set { this.skills[index] = value; }
}
which takes an int index and returns a SkillValue.
BUT you are causing a runtime StackOverlowExeption due to a recursive call of Science.
You can't use Science inside of the getter or setter of equally called property!
Imagine using the getter as example:
You would call
var test = Science;
so it executes the getter
return Character.skills[Science].Value;
but well ... in order to know the value of Science in order to use it here as the index it would again have to execute the getter so again
return Character.skills[Science].Value;
and by now you hopefully get what I mean.
Solution
You property should actually as guessed before rather look like
public int Science
{
get { return Character.skills[SkillType.Science]; }
set { Character.skills[SkillType.Science] = value; }
}

Retrieve a Customized String Value

Goal:
Retrieve a string value that is "1_2_3" om the code myListAnimals. In the future, the value can be random.
I need to add a "_" between numbers.
Problem:
I don't know how to do it by using LINQ?
public class Animal
{
private void int _number;
private void string _name;
private bool display;
public int Number
{
get { return _number;}
set { _number = value; }
}
public int Name
{
get { return _name;
set { _name = value; }
}
public bool Display
{
get { return display;
set { display = value; }
}
}
List<Animal> myListAnimal = new List<Animal>
Animal myAnimal = new List<Animal>
myAnimal.Number = 1;
myAnimal.Name = "Dog";
myAnimal.Display = True;
myAnimals.add(myAnimal )
Animal myAnimal2 = new List<Animal>
myAnimal2.Number = 2;
myAnimal2.Name = "Cat";
myAnimal2.Display = True;
myAnimals.add(myAnimal2)
Animal myAnimal3 = new List<Animal>
myAnimal3.Number = 3;
myAnimal3.Name = "Pig";
myAnimal3.Display = True;
myAnimals.add(myAnimal3)
Animal myAnimal4 = new List<Animal>
myAnimal4.Number = 4;
myAnimal4.Name = "Sheep";
myAnimal4.Display = false;
myAnimals.add(myAnimal4)
Note: Your code sample isn't valid C#. I assume that you can fix that (it's pretty simple basic changes that need to be made). That said:
Yes, you can use LINQ to concatenate strings, which is ultimately what you're doing.
var concat = myListAnimal
.Where(a => a.Display)
.Select(a => a.Number.ToString())
.Aggregate((current, next) => current + "_" + next);
Console.WriteLine(concat);
Would output with your data:
1_2_3
Where() filters the values where Display != true
Select() projects the number values to a sequence of strings
and Aggregate() does the concatenation.
your code is not valid. First fix it and try this.
var concat =string.Join("_", myListAnimal.Select(a => a.Number).ToArray());
Try using StringBuilder and ForEach extension method.
StringBuilder sb = new StringBuilder();
myAnimals.ForEach(x=> sb.AppendFormat("{0}_",x.Number));

C# NullReferenceException in class validation method

I am trying to add a helper method to scrub out any non-alphanumeric characters in my class. However, I keep getting the error
NullReferenceException: Object reference not set to an instance of an object.
Not sure what I'm doing wrong here since I thought this was the proper way to set up any kind of validation within a class. Any suggestions would be appreciated.
private string agentId;
public string AgentId
{
get { return agentId; }
set { agentId = this.scrubAgentId(); }
}
private string scrubAgentId()
{
char[] arr = this.AgentId.ToCharArray();
arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c))));
return new string(arr);
}
This isn't really right at all. You're discarding the value when performing your set. It should probably look something more like this:
private string agentId;
public string AgentId
{
get { return agentId; }
set { agentId = this.scrubAgentId(value); }
}
private string scrubAgentId(string value)
{
if(value == null)
return value;
char[] arr = value.ToCharArray();
arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c))));
return new string(arr);
}
In the set part of the property you have an implicit object, value which holds the value you want to set... Use this value as your base
private string agentId;
public string AgentId
{
get { return agentId; }
set { agentId = value; } // manipulate value here using your method
}
Are you initialising agentid anywhere first?
Its failing on char[] arr = this.AgentId.ToCharArray();
You never reference the value in your setter. You want to do something like this:
private string agentId;
public string AgentId
{
get
{
return agentId ;
}
set
{
agentId = new string( value.ToCharArray().Where( c => c.IsLetterOrDigit(c) ) ) ;
}
}

question about linq select and ToList()

I have a problem with returning a list by executing a Select LINQ query. This is the query:
var data = Repository<EducationString>
.Find()
.ToList()
.Select(p => new EducationStringModel() {
Id = p.Id,
Title = p.Title,
EducationDegree=p.EducationDegree })
.ToList();
As you can see I used ToList() 2 times. I don't know why but when I delete the first ToList() I see this error, "Index was outside the bounds of the array", but by having both ToList() there is no problem.
Would it help if I said EducationDegree in EducationStringModel is an IList<EducationDegree>?
Is there anybody who knows the reason?
#Mark :its L2O
if u need to see the classes:
public class EducationStringModel
{
private IList _educationDegree = new List();
public IList EducationDegree
{
get
{
if (_educationDegree == null)
{
_educationDegree = new List();
}
return _educationDegree;
}
set { _educationDegree = value; }
}
public int? Id { get; set; }
public string Title { get; set; }
}
public class EducationString{
private string _title;
private IList _educationExperiences;
private IList _educationDegree;
virtual public string Title
{
get { return _title; }
set { _title = value; }
}
virtual public IList<EducationExperience> EducationExperiences
{
get
{
if (_educationExperiences == null)
{
_educationExperiences = new List<EducationExperience>();
}
return _educationExperiences;
}
set
{
_educationExperiences = value;
}
}
virtual public IList<EducationDegree> EducationDegree
{
get
{
if (_educationDegree == null)
{
_educationDegree = new List<EducationDegree>();
}
return _educationDegree;
}
set
{
_educationDegree = value;
}
}
}
Is that the actual code? The only unclear thing there is: what does Find() return?
It sounds like the ToList is helping here by breaking composition and using LINQ-to-Objects, in which case AsEnumerable() should work just as well. After that you just do a Select (which for L2O just takes each item in turn and applies the map). If Find() is something more exotic, it sounds like a bug in that LINQ provider (or perhaps more fairly: that provider struggling to cope with an atypical construct). Hard to say more without a fully reproducible example.

C# StackOverflowException

Problem: I am trying to update a List. If a certain item's ID already exists in the List, I want to add onto that item's quantity. If not, then I want to add another item to the list.
cart = (List<OrderItem>)Session["cart"];
for(int counter = cart.Count-1; counter >= 0; counter--)
{
if (cart[counter].productId == item.productId)
{
cart[counter].productQuantity += item.productQuantity;
}
else if (counter == 0)
{
cart.Add(item);
}
}
cart[counter] and item represent an instance(s) of a custom object of mine. Currently when I finally find a matching ID, everything APPEARS as though it should work, but I get a StackOverflowException thrown in my custom object class.
public int productQuantity
{
get
{
return _productQuantity;
}
set
{
productQuantity = value;
}
}
It gets thrown right at the open-bracket of the "set". Could somebody please tell me what the heck is wrong because I've been going at this for the past 2+ hours to no avail. Thank you in advance.
the problem is in your setter of the productQuantity
it should read:
set
{
_productQuantity= value;
}
edit (naming convention):
public class Vertex3d
{
//fields are all declared private, which is a good practice in general
private int _x;
//The properties are declared public, but could also be private, protected, or protected internal, as desired.
public int X
{
get { return _x; }
set { _x = value; }
}
}
Replace productQuantity = value; with _productQuantity = value; (you're recurring infinitely by calling the setter over and over)
Why not just use this instead?
public int productQuantity { get; set; }
But the flaw was in the _
public int productQuantity {
get {
return _productQuantity;
}
set {
_productQuantity = value;
}
}
cart = (List<OrderItem>)Session["cart"];
int index = cart.Find(OrderItem => OrderItem.productId == item.productId);
if(index == -1) {
cart.Add(item);
} else {
cart[index].productQuantity += item.productQuantity;
}
public int productQuantity
{
get
{
return _productQuantity;
}
set
{
_productQuantity = value; //this should be an assignment to a member variable.
}
}

Categories

Resources