I have two list that i want to compare. In one i have a small amount of objects and in the other im sure i have the objects from the first list plus others.
Im trying to do an intersection to get the objects from the second list that are in my first list.To do that i have the object inside the two list is of type
public class ReportDataImportant : ReportData
{
public String IdTitular { get; set; }
public String Identificacion { get; set; }
public String IndicadorPersona { get; set; }
public String Titular { get; set; }
public decimal Porcentaje { get; set; }
public int Cotitulares { get; set; }
public String IndicadorNacionalidad { get; set; }
public String Nacionalidad { get; set; }
}
I have also a comparer class like this:
public class ReportDataComparer : IEqualityComparer<ReportDataImportant>
{
public bool Equals(ReportDataImportant x, ReportDataImportant y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) ||
Object.ReferenceEquals(y, null))
return false;
return x.Identificacion.Equals(y.Identificacion);
}
public int GetHashCode(ReportDataImportant obj)
{
if (Object.ReferenceEquals(obj, null)) return 0;
return obj.Identificacion.GetHashCode();
}
}
An to make the intersection i call it with this expresion :
var reult = _list1.Intersect(List2, new ReportDataComparer()).ToList();
However im not getting the result im expecting. Does somebody know what is happening?
Related
I'm trying to validate if both my objects have the same values.
here's my class
public class myclass
{
public List<c1> List1{ get; set; }
public List<c2> List2{ get; set; }
public List<c3> List3{ get; set; }
}
public class c1
{
public int Number{ get; set; }
public string Name{ get; set; }
public bool IsAvailable{ get; set; }
}
public class c2
{
public int Id{ get; set; }
public string Text{ get; set; }
public GUID Guid{ get; set; }
}
public class c3
{
public int? Age{ get; set; }
public string Role{ get; set; }
public bool IsDeleted{ get; set; }
}
I have 2 instances of this class and I want to compare the data between both the instances and check if they both are the same or not.
I've tried Serializing both the objects and comparing but that's not working as the items in the list can be in a different order.
I've also tried getting HashSet of individual lists and checking if they are equal.
var s1 = new HashSet<c1>(list1);
var s2= new HashSet<c1>(list2);
return s1.SetEquals(s2);
One solution would be to first order the lists using a standard order, like numeric or alphabetic depending on the types, and then trying something like this
if (myclassInstance1.list1.SequenceEqual(myclassInstance2.list1))
{
//Repeat the cycle 2 more times and then //your code
}
Since this one works comparing the sequence you need to first order the lists and to do that you can maybe use this
EDIT: This is the documentation for the list.sequenceEquals() method
The best way to do this is if you explicitly implement the models with IEqualityComparer in .NET.
using System;
using System.Collections.Generic;
public class Program
{
public class MyClass
{
public List<C1> C1List { get; set; }
public List<C2> C2List { get; set; }
}
public class C1 : IEqualityComparer<C1>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Equals(C1 x, C1 y)
{
if(string.Equals(x.FirstName, y.FirstName, StringComparison.OrdinalIgnoreCase)
&& string.Equals(x.LastName, y.LastName, StringComparison.OrdinalIgnoreCase))
return true;
return false;
}
public int GetHashCode(C1 c)
{
return c.FirstName.Length * c.LastName.Length;
}
}
public class C2 : IEqualityComparer<C2>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Equals(C2 x, C2 y)
{
if(string.Equals(x.FirstName, y.FirstName, StringComparison.OrdinalIgnoreCase)
&& string.Equals(x.LastName, y.LastName, StringComparison.OrdinalIgnoreCase))
return true;
return false;
}
public int GetHashCode(C2 c)
{
return c.FirstName.Length * c.LastName.Length;
}
}
}
The IEqualityComparer will give you full control on "the parameters based on which you call 2 objects equal".
As for the above implementation, I have considered the 2 objects are equal if the FirstName and the LastName are same.
Try to order the list,and then compare the data in it:
List<c1> l1 = list1.OrderBy(c => c.Number).ToList();
List<c1> l2 = list2.OrderBy(c => c.Number).ToList();
bool equalValue = true;
if (l1.Count() == l2.Count()) {
for (int i = 0; i < l1.Count(); i++){
if (l1[i].IsAvailable != l2[i].IsAvailable || l1[i].Number != l2[i].Number || l1[i].Name != l2[i].Name)
{
equalValue = false;
break;
}
}
}
else {
equalValue = false;
}
return equalValue;
I have the following class to store objects from a REST API call from SharePoint:
[Serializable]
public class DocumentSearchResult
{
public string TotalCount { get; set; }
public string DocumentPath { get; set; }
public string DocumentTitle { get; set; }
public string DocumentSize { get; set; }
public string DocumentAuthor { get; set; }
public string DocumentDescription { get; set; }
public string DocumentFileExtension { get; set; }
public double DocumentRank { get; set; }
public Int64 DocumentDocId { get; set; }
public Int64 DocumentWorkId { get; set; }
public DateTime DocumentWrite { get; set; }
public string DocumentParentLink { get; set; }
public DateTime DocumentLastModifiedDate { get; set; }
public string DocumentFileType { get; set; }
//These next set of properties are used for Viewing the results in embedded or preview
public string DocumentRedirectedEmbededURL { get; set; }
public string DocumentRedirectPreviewURL { get; set; }
public string DocumentRedirectURL { get; set; }
}
I create a list of these objects in my code:
var docReturnResult = new List<DocumentSearchResult>();
I have another list I create using:
var filterList = this.Where(x => x.TenantId == TenantId);
this will return an IQueryable list that contains a value I need to filter the second list. The filterList has an attribute called SharePointId (x => x.SharePointId) that I need to use to filter the docReturnResult list. So I need to compare the filterList SharePointId to the docReturnResult DocumentDocId and remove any objects in the docReturnResult list that don't match the SharePointId's in the filterList.
This is what I tried last:
var trimResults = new DocumentSearchResult();
trimResults = docReturnResult.RemoveAll(x => x.DocumentDocId != filterList.Where(y => y.SharePointId));
but I get an error:
Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type.
Any help is much appreciated.
Try this, it should remove all documents from docReturnResult where match is not found in filterList
docReturnResult.RemoveAll(x => !filterList.Any(y => y.SharePointId == x.DocumentDocId));
Root cause of your error -
x.DocumentDocId != filterList.Where(y => y.SharePointId)
Right hand side will return IQuarable object and you are trying to compare it with DocumentDocId which will not work.
Edit
You don't need a new variable trmResults, as RemoveALL on docReturnResult will trim the same object, so you can just return docReturnResult
return docReturnResult.RemoveAll(x => !filterList.Any(y => y.SharePointId == x.DocumentDocId));
I have a class that contains the details of a Match, the structure is this:
public class Match
{
public string TeamHome { get; set; }
public string TeamAway { get; set; }
public string Result { get; set; }
public League League { get; set; }
}
public class League
{
public string Name { get; set; }
public string Country{ get; set; }
}
I bound a list of Match to a DataGrid, but I have a problem, when I apply the sorting on that DataGrid I get:
at least one object must implement IComparable
this happen only when I have already added items to the Matches collection, that is the collection bounded by the DataGrid and is defined in this way:
List<Match> Matches = new List<Match>();
I tried to fix this error implementing the IComparable interface:
public class Match : IComparable<Match>
{
public string TeamHome { get; set; }
public string TeamAway { get; set; }
public string Result { get; set; }
public League League { get; set; }
public int CompareTo(Match other)
{
return this.CompareTo(other);
}
}
the error still happen.
So I need to ask these questions:
Should I implement IComparable to all properties?
How can I investigate more?
Thanks for any help.
You need to add your own implementation to CompareTo(Match match) method
Something like:
public int CompareTo(object obj)
{
Match match = obj as Match;
if(match != null)
{
return (TeamHome == match.TeamHome
&& TeamAway == match.TeamAway
&& Result == match.Result
&& League.GetHashCode() == match.League.GetHashCode())
? 0 : -1;
}
return -1;
}
And in your class declaration:
public class Match : IComparable
without the <Match>
But in this case i think it would make more sense to overload the Equals operator like this:
public override bool Equals(object other)
{
Match match = other as Match;
if(match != null)
{
return TeamHome == match.TeamHome
&& TeamAway == match.TeamAway
&& Result == match.Result
&& League.GetHashCode() == match.League.GetHashCode();
}
return false;
}
Currently writing a simple reservation. Right now I have a multidimensional string array that holds the passengers name and I am trying to iterate through that array and see whether there are any open seats so I know whether or not to add them to a waiting list.
// Check how many seats are taken
for (int i = 0; i <= nameArray.GetUpperBound(0); i++)
{
for (int j = 0; j <= nameArray.GetUpperBound(1); j++)
{
if (nameArray[i, j] == "")
{
seatsFilled--;
}
else
{
seatsFilled++;
}
}
}
For some reason when I debug, I notice that this line
if (nameArray[i, j] == "")
Doesn't do anything at all and gets skipped over despite there being no names in the array. I cannot for the life of me figure out why. Any suggestions?
One of the reason i can see is the comparison may have the whitespace. Try this
if(string.IsNullOrWhiteSpace(nameArray[i, j]))
I would do something like this:
First I would create some interfaces and models that would define the structure of the seat. Make sure to account for seat restrictions.
public interface ISeat
{
int RowNumber { get; }
string SeatLetter { get; }
PassangerModel Passenger { get; }
}
We want to allow some of the seats to be restricted based on passenger age and height. Hard coding that into each seat is nasty so instead I created a SeatRestriction class that has a predicate in it. This predicate will take the passenger model in and return a result. So for example you could create a SeatRestriction that checked a passengers height or age to make sure they can open emergency doors.
public class SeatRestriction
{
public Predicate<PassangerModel> Restriction { get; private set; }
public SeatRestriction(Predicate<PassangerModel> restriction)
{
Restriction = restriction;
}
}
The passenger model can actually be much more verbose than this. I'm assuming here no dietary needs. Maybe this is a reservation system for Spirit Airlines.
public class PassangerModel
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string CreditCardName { get; set; }
public string CreditCardNumber { get; set; }
public string CreditCardExpiration { get; set; }
public string CreditCardSecurityPin { get; set; }
}
Next We come to our seat class. This class allows us to see if a passenger is assigned to the seat. Take note that it also asserts prior to adding the passenger to the seat if the passenger meets the restrictions, if any.
public interface IRestrictedSeat
{
List<SeatRestriction> Restrictions { get; }
bool AssertQualifiedPassenger(PassangerModel passenger);
}
public class Seat : ISeat, IRestrictedSeat
{
public bool IsSeatReserved { get { return Passenger != null; } }
public int RowNumber { get; private set; }
public string SeatLetter { get; private set; }
public PassangerModel Passenger { get; private set; }
public List<SeatRestriction> Restrictions { get; private set; }
public Seat(int rowNumber, string seatLetter)
{
Restrictions = new List<SeatRestriction>();
RowNumber = rowNumber;
SeatLetter = seatLetter;
}
public bool TryAddPassenger(PassangerModel passanger)
{
if (AssertQualifiedPassenger(passanger))
{
Passenger = passenger;
return true;
}
else
{
return false;
}
}
public bool AssertQualifiedPassenger(PassangerModel passenger)
{
foreach(SeatRestriction restriction in Restrictions)
{
if (!restriction.Restriction(passenger))
{
return false;
}
}
return true;
}
}
Finally we get to the row. Our row knows how manys seats it has and what its number is. You should be able to add seats to it and then call GetAvailableSeats to get the seats that are left in this row.
public class SeatRow
{
public int TotalSeats { get; private set; }
public int RowNumber { get; private set; }
public List<Seat> Seats { get; private set; }
public SeatRow(int seatsInRow, int rowNumber)
{
TotalSeats = seatsInRow;
RowNumber = rowNumber;
}
public bool TryAddSeatToRow(Seat seat)
{
if(Seats.Count <= TotalSeats && seat.RowNumber == RowNumber)
{
Seats.Add(seat);
return true;
}
else
{
return false;
}
}
public IEnumerable<Seat> GetAvailableSeats()
{
return Seats.Where(seat => seat.IsSeatReserved == false);
}
}
The long and short of this answer is there's a million ways to solve CIS problems and to not rely on stack overflow while you're in school/learning. Good luck and welcome to the club :-)
if (nameArray[i, j] == "")
Doesn't do anything at all and gets skipped over despite there being no names in the array.
That line is inside a loop that iterates through the items in the array. If the array is empty then this will never get executed.
I have following model class
public class AssignUserViewModel
{
public IEnumerable<User> Viewrlist { get; set; }
public IEnumerable<User> AssignedViewrlist { get; set; }
}
I'm binding values to it like below. and comparing objassignuser.Viewrlisttry and objassignuser.AssignedViewrlist then remove duplicate from objassignuser.Viewrlisttry like below. but this is not working properly
AssignUserViewModel objassignuser = new AssignUserViewModel();
objassignuser.Viewrlist = ..
objassignuser.AssignedViewrlist = ..
IEnumerable<User> result = (objassignuser.Viewrlist).Except( objassignuser.AssignedViewrlist );
objassignuser.Viewrlist = null;
objassignuser.Viewrlist = result;
You must make the User class implement the IEquatable<T> interface.
A simple implementation can look like this:
class User: IEquatable<User>
{
public int Id{ get; set; }
public string UserName { get; set; }
public bool Equals(User other)
{
return Id == other.Id;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
For more info have a look here.