1

I have these two lists result and resultNew:

data.AddMapping<Employee>(x => x.Name, "Name");
data.AddMapping<Employee>(x => x.Code, "Code");
data.AddMapping<Employee>(x => x.WorkingStatus, "Working Status");
var result = (from x in data.Worksheet<Employee>("Tradesmen")
              select x).ToList();


dataNew.AddMapping<Employee>(x => x.Name, "Name");
dataNew.AddMapping<Employee>(x => x.Code, "Code");
dataNew.AddMapping<Employee>(x => x.WorkingStatus, "Working Status");
var resultNew = (from x in dataNew.Worksheet<Employee>("On Leave")
                 select x).ToList();

where Employee is a simple c# code that contains code, name and workingStatus fields

I want to take the data which its code is the resultNew and not in the result

I tried this:

var newEmployees = resultNew.Except(Code = result.Select(s => s.Code)).ToList();

but I got syntax error:

System.Collections.Generic.List' does not contain a definition for 'Except' and the best extension method overload 'System.Linq.Enumerable.Except(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable)' has some invalid arguments

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Anastasie Laurent
  • 877
  • 2
  • 14
  • 26
  • If `resultNew` is `List` *(Codes)*, then you can do: `resultNew.Except(result.Select(s=> s.Code).ToList()`, but that will give you difference of Codes. – Habib Sep 05 '14 at 17:26
  • @Habib no it is list on `Employee` – Anastasie Laurent Sep 05 '14 at 17:27
  • 1
    `Except` is used for dealing with 2 enumerables. Basically "take these 2 lists of the same type and only return me elements where items aren't in this other list". – TyCobb Sep 05 '14 at 17:29
  • @TyCobb but these are lists on `Employee` object, and I want to differenciate depending on `Employy code` not because some time we have employee with the same name but differeenct code. (code is like ID) got me pleaes? – Anastasie Laurent Sep 05 '14 at 17:32
  • No, I got it. Just informing you what `Except` actually does and why it is erroring. – TyCobb Sep 05 '14 at 17:34

1 Answers1

4

You can create a HashSet for Code of new employees and then use it like:

HashSet<string> resultCodes = new HashSet<string>(result.Select(r => r.Code));
List<Employee> newEmployees = resultNew.Where(r => !resultCodes.Contains(r.Code))
                                    .ToList();

You can also override Equals and GetHashCode for your class Employee base on property Code and then you can use Except like:

class Employee
{
    protected bool Equals(Employee other)
    {
        return string.Equals(Code, other.Code);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Employee) obj);
    }

    public override int GetHashCode()
    {
        return (Code != null ? Code.GetHashCode() : 0);
    }

    public string Name { get; set; }
    public string Code { get; set; }
    public string WorkingStatus { get; set; }

}

and then:

var newEmployees = resultnew.Except(result).ToList();

Remember the above implementation of Equals and GetHashCode only considers Code property. See this question How do you implement GetHashCode for structure with two string, when both strings are interchangeable

Community
  • 1
  • 1
Habib
  • 219,104
  • 29
  • 407
  • 436
  • I was going to do it with a `IEnumerable` by selecting the codes from resultNew (`var resultCodes = resultNew.Select(r => r.Code);`). Is HashSet more performant than my method? – Brandon Sep 05 '14 at 17:37
  • @Brandon, yes it is. For a smaller data set you will not notice the difference. Without `HashSet` one can do: `resultNew.Where(r=> result.Select(s=> s.Code).Contains(r.Code))` – Habib Sep 05 '14 at 17:38
  • I didn't think about HashSet until I saw your answer. Thanks for the clarification with larger data sets. Glad I asked. – Brandon Sep 05 '14 at 17:40
  • thanks for your answer, but maybe you mis understand my question, i want the employees who exist just in `resultNew` , but your code seems to give me the emplployees which exist just in `result` am i right please? – Anastasie Laurent Sep 05 '14 at 17:41
  • @AnastasieLaurent, with overriding `Equals` and `GetHashCode` and using `Except` you will get only those employees which exist in `resultNew` but don't exist in `result` like `new[] {1, 2, 3,}.Except(new[] {3, 4, 5}).ToList();` would give you `{1,2}` – Habib Sep 05 '14 at 17:47
  • @AnastasieLaurent, also modified in the first option. – Habib Sep 05 '14 at 17:49
  • I am sorry but really the result of your code is incorrect, i added a new employee and ran your code, but the new employee didn't appear – Anastasie Laurent Sep 05 '14 at 17:53
  • @AnastasieLaurent, which code you are trying ? first one or did you override `Equals` and `GetHashCode` and using `Except` ? – Habib Sep 05 '14 at 17:54
  • @AnastasieLaurent, missed the `!` in the condition, try now. It is working just like Except. Tested on my machine. – Habib Sep 05 '14 at 18:01