I have two collections and I want to loop through each element and compare the corresponding elements in each collection for equality, thus determining if the collections are identical.
Is this possible with a foreach loop or must I use a counter and access the elements by index?
Generally speaking is there a preferred method for comparing collections for equality, like overloading an operator?
TIA.
You can use .SequenceEqual method which is used for this purpose. Read More.
Examples below if link is down or removed for some reason.
Determines whether two sequences are equal by comparing the elements
by using the default equality comparer for their type.
The SequenceEqual(IEnumerable, IEnumerable)
method enumerates the two source sequences in parallel and compares
corresponding elements by using the default equality comparer for
TSource, Default. The default equality comparer, Default, is used to
compare values of the types that implement the IEqualityComparer
generic interface. To compare a custom data type, you need to
implement this interface and provide your own GetHashCode and Equals
methods for the type.
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void SequenceEqualEx1()
{
Pet pet1 = new Pet { Name = "Turbo", Age = 2 };
Pet pet2 = new Pet { Name = "Peanut", Age = 8 };
// Create two lists of pets.
List<Pet> pets1 = new List<Pet> { pet1, pet2 };
List<Pet> pets2 = new List<Pet> { pet1, pet2 };
bool equal = pets1.SequenceEqual(pets2);
Console.WriteLine(
"The lists {0} equal.",
equal ? "are" : "are not");
}
/*
This code produces the following output:
The lists are equal.
*/
If you want to compare the actual data of the objects in the sequences
instead of just comparing their references, you have to implement the
IEqualityComparer generic interface in your class. The following
code example shows how to implement this interface in a custom data
type and provide GetHashCode and Equals methods.
public class Product : IEquatable<Product>
{
public string Name { get; set; }
public int Code { get; set; }
public bool Equals(Product other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
//Check whether the products' properties are equal.
return Code.Equals(other.Code) && Name.Equals(other.Name);
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
//Get hash code for the Name field if it is not null.
int hashProductName = Name == null ? 0 : Name.GetHashCode();
//Get hash code for the Code field.
int hashProductCode = Code.GetHashCode();
//Calculate the hash code for the product.
return hashProductName ^ hashProductCode;
}
}
Usage:
Product[] storeA = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };
Product[] storeB = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };
bool equalAB = storeA.SequenceEqual(storeB);
Console.WriteLine("Equal? " + equalAB);
/*
This code produces the following output:
Equal? True
*/
Related
I'm desperately trying to delete all the items with a list of the same value inside.
Here's the code:
private void Button_deleteDouble_MouseDown(object sender, EventArgs e)
{
boardGenerate.Add(new BoardInformation(146, new List<string> { "test" }));
boardGenerate.Add(new BoardInformation(545, new List<string> { "test" }));
boardGenerate = boardGenerate.DistinctBy(x => x.positionQueen).ToList();
}
Normally, since the two lists inside the object are the same, the .DistinctBy() command should remove one of the two objects.
But no, my object list still has the same two objects with the same list
.positionQueen is the name of the variable containing the list
Could somebody help me?
Edit :
The DistinctBy() method comes from MoreLinq.
And this is my BoardInformation class:
public class BoardInformation
{
public BoardInformation(int nbQueen, List<string> positionQueen)
{
this.nbQueen = nbQueen;
this.positionQueen = positionQueen;
}
public int nbQueen { get; set; }
public List<string> positionQueen { get; set; }
}
Set-based operations like Distinct and DistinctBy need a way of determining whether two values are the same. You're using DistinctBy, so you're already asking MoreLINQ to compare the "inner lists" for equality - but you're not saying how to do that.
List<T> doesn't override Equals or GetHashCode, which means it inherits the reference equality behaviour from System.Object. In other words, if you create two separate List<T> objects, they won't compare as equal, even if they have the same content. For example:
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
Console.WriteLine(list1.Equals(list2)); // False
You need to tell DistinctBy how you want to compare the two lists, using an IEqualityComparer<T> - where T in this case is List<string> (because that's the type of BoardInformation.positionQueen.
Here's an example of a generic ListEqualityComparer you could use:
using System;
using System.Collections.Generic;
using System.Linq;
public sealed class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
private readonly IEqualityComparer<T> elementComparer;
public ListEqualityComparer(IEqualityComparer<T> elementComparer) =>
this.elementComparer = elementComparer;
public ListEqualityComparer() : this(EqualityComparer<T>.Default)
{
}
public bool Equals(List<T> x, List<T> y) =>
ReferenceEquals(x, y) ? true
: x is null || y is null ? false
// Delegate to LINQ's SequenceEqual method
: x.SequenceEqual(y, elementComparer);
public int GetHashCode(List<T> obj)
{
if (obj is null)
{
return 0;
}
// Just a very simple hash implementation
int hash = 23;
foreach (var item in obj)
{
hash = hash * 31 +
(item is null ? 0
: elementComparer.GetHashCode(item));
}
return hash;
}
}
You'd then pass that to DistinctBy, like this:
// We're fine to use the default *element* comparer (string.Equals etc)
var comparer = new ListEqualityComparer<string>();
boardGenerate = boardGenerate.DistinctBy(x => x.positionQueen, comparer).ToList();
Now DistinctBy will call into the comparer, passing in the lists, and will consider your two BoardInformation objects are equal - so only the first will be yielded by DistinctBy, and you'll end up with a list containing a single item.
It comes down to whether a equality check is using referential equality or value equality...you want value equality based on a specific property and that has to be done by hand.
When there is no IEqualityComparer provided which can used to compare individual objects (which is need by the Distinct call), the system determines the equality from each item's references by using their derived object low level service method call of GetHashCode from each reference; hence a reference difference is done and all your values in the list are unique (not equal) regardless of similar property values.
What you are looking for is to have value equality checked specifically for the nbQueenProperty.
To fully utilize Distinct one must create a IEqualityComparer and modify the GetHashCode. By specifing the hash value which can make objects equal...you can weed out the same positionQueen (or other properties) instances out.
Example
public class MyClass
{
public string Name { get; set; }
public int nbQueen { get; set; }
}
Equality comparer to weed out all nbQueen similarities:
class ContactEmailComparer : IEqualityComparer < MyClass >
{
public bool Equals(MyClass x, MyClass y)
{
return x.nbQueen.Equals(y.nbQueen); // Compares by calling each `GetHashCode`
}
public int GetHashCode(MyClass obj)
{
return obj.nbQueen.GetHashCode(); // Add or remove other properties as needed.
}
}
Test code
var original = new List<MyClass>()
{
new MyClass() { nbQueen = 1, Name="Alpha" },
new MyClass() { nbQueen = 1, Name="Omega" },
new MyClass() { nbQueen = 3, Name="Delta" }
};
IEqualityComparer<MyClass> comparer = new ContactEmailComparer();
var newOne = original.Distinct( comparer ).ToList();
Result of the value of newOne :
To be clear...
... .DistinctBy() command should remove one of the two objects.
Does not remove anything. It returns a reference to a new list that should be distinct via the equality operation. The original list (the reference to it) does not change.
LINQ solution
because you have another List inside your class you can not use District or DistrictBy, alternatively, you can use LINQ to filter the list.
boardGenerate = (from b in boardGenerate
from l in b.positionQueen
group new { l,b } by l into g
select g.First().b
).ToList();
// this returns just first duplicate item like district
I have some classes that contain several fields. I need to compare them by value, i.e. two instances of a class are equal if their fields contain the same data. I have overridden the GetHashCode and Equals methods for that.
It can happen that these classes contain circular references.
Example: We want to model institutions (like government, sports clubs, whatever). An institution has a name. A Club is an institution that has a name and a list of members. Each member is a Person that has a name and a favourite institution. If a member of a certain club has this club as his favourite institution, we have a circular reference.
But circular references, in conjunction with value equality, lead to infinite recursion. Here is a code example:
interface IInstitution { string Name { get; } }
class Club : IInstitution
{
public string Name { get; set; }
public HashSet<Person> Members { get; set; }
public override int GetHashCode() { return Name.GetHashCode() + Members.Count; }
public override bool Equals(object obj)
{
Club other = obj as Club;
if (other == null)
return false;
return Name.Equals(other.Name) && Members.SetEquals(other.Members);
}
}
class Person
{
public string Name { get; set; }
public IInstitution FavouriteInstitution { get; set; }
public override int GetHashCode() { return Name.GetHashCode(); }
public override bool Equals(object obj)
{
Person other = obj as Person;
if (other == null)
return false;
return Name.Equals(other.Name)
&& FavouriteInstitution.Equals(other.FavouriteInstitution);
}
}
class Program
{
public static void Main()
{
Club c1 = new Club { Name = "myClub", Members = new HashSet<Person>() };
Person p1 = new Person { Name = "Johnny", FavouriteInstitution = c1 }
c1.Members.Add(p1);
Club c2 = new Club { Name = "myClub", Members = new HashSet<Person>() };
Person p2 = new Person { Name = "Johnny", FavouriteInstitution = c2 }
c2.Members.Add(p2);
bool c1_and_c2_equal = c1.Equals(c2); // StackOverflowException!
// c1.Equals(c2) calls Members.SetEquals(other.Members)
// Members.SetEquals(other.Members) calls p1.Equals(p2)
// p1.Equals(p2) calls c1.Equals(c2)
}
}
c1_and_c2_equal should return true, and in fact we (humans) can see that they are value-equal with a little bit of thinking, without running into infinite recursion. However, I can't really say how we figure that out. But since it is possible, I hope that there is a way to resolve this problem in code as well!
So the question is: How can I check for value equality without running into infinite recursions?
Note that I need to resolve circular references in general, not only the case from above. I'll call it a 2-circle since c1 references p1, and p1 references c1. There can be other n-circles, e.g. if a club A has a member M whose favourite is club B which has member N whose favourite club is A. That would be a 4-circle. Other object models might also allow n-circles with odd numbers n. I am looking for a way to resolve all these problems at once, since I won't know in advance which value n can have.
An easy workaround (used in RDBMS) is to use a unique Id to identify a Person(any type). Then you don't need to compare every other property and you never run into such cuircular references.
Another way is to compare differently in Equals, so provide the deep check only for the type of the Equals and not for the referenced types. You could use a custom comparer:
public class PersonNameComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
if(object.ReferenceEquals(x, y)) return true;
return x.Name == y.Name;
}
public int GetHashCode(Person obj)
{
return obj?.Name?.GetHashCode() ?? int.MinValue;
}
}
Now you can change the Equals implementation of Club to avoid that the Members(Persons) will use their deep check which includes the institution but only their Name:
public override bool Equals(object obj)
{
if (Object.ReferenceEquals(this, obj))
return true;
Club other = obj as Club;
if (other == null)
return false;
var personNameComparer = new PersonNameComparer();
return Name.Equals(other.Name)
&& Members.Count == other.Members.Count
&& !Members.Except(other.Members, personNameComparer).Any();
}
You notice that i can't use SetEquals because there is no overload for my custom comparer.
Following the suggestion of Dryadwoods, I changed the Equals methods so that I can keep track of the items that were already compared.
First we need an equality comparer that checks reference equality for corresponding elements of pairs:
public class ValuePairRefEqualityComparer<T> : IEqualityComparer<(T,T)> where T : class
{
public static ValuePairRefEqualityComparer<T> Instance
= new ValuePairRefEqualityComparer<T>();
private ValuePairRefEqualityComparer() { }
public bool Equals((T,T) x, (T,T) y)
{
return ReferenceEquals(x.Item1, y.Item1)
&& ReferenceEquals(x.Item2, y.Item2);
}
public int GetHashCode((T,T) obj)
{
return RuntimeHelpers.GetHashCode(obj.Item1)
+ 2 * RuntimeHelpers.GetHashCode(obj.Item2);
}
}
And here is the modified Equals method of Club:
static HashSet<(Club,Club)> checkedPairs
= new HashSet<(Club,Club)>(ValuePairRefEqualityComparer<Club>.Instance);
public override bool Equals(object obj)
{
Club other = obj as Club;
if (other == null)
return false;
if (!Name.Equals(other.Name))
return;
if (checkedPairs.Contains((this,other)) || checkedPairs.Contains((other,this)))
return true;
checkedPairs.Add((this,other));
bool membersEqual = Members.SetEquals(other.Members);
checkedPairs.Clear();
return membersEqual;
}
The version for Person is analogous. Note that I add (this,other) to checkedPairs and check if either (this,other) or (other,this) is contained because it might happen that after the first call of c1.Equals(c2), we end up with a call of c2.Equals(c1) instead of c1.Equals(c2). I am not sure if this actually happens, but since I can't see the implementation of SetEquals, I believe it is a possibility.
Since I am not happy with using a static field for the already checked pairs (it will not work if the program is concurrent!), I asked another question: make a variable last for a call stack.
For the general case that I am interested in
-- where we have classes C1, ..., Cn where each of these classes can have any number of VALUES (like int, string, ...) as well as any number of REFERENCES to any other classes of C1, ..., Cn (e.g. by having for each type Ci a field ICollection<Ci>) --
the question "Are two objects A and B equal?", in the sense of equality that I described here,
seems to be EQUIVALENT to
the question "For two finite, directed, connected, colored graphs G and H, does there exist an isomorphism from G to H?".
Here is the equivalence:
graph vertices correspond to objects (class instances)
graph edges correspond to references to objects
color corresponds to the conglomerate of values and the type itself (i.e. colors of two vertices are the same if their corresponding objects have the same type and the same values)
That's an NP-hard question, so I think I'm going to discard my plan to implement this and go with a circular-reference-free approach instead.
I've been researching IEqualityComparer and IEquitable.
From posts such as What is the difference between IEqualityComparer<T> and IEquatable<T>? the difference between the two is now clear. "IEqualityComparer is an interface for an object that performs the comparison on two objects of the type T."
Following the example at https://msdn.microsoft.com/en-us/library/ms132151(v=vs.110).aspx the purpose of IEqualityComparer is clear and simple.
I've followed the example at https://dotnetcodr.com/2015/05/05/implementing-the-iequatable-of-t-interface-for-object-equality-with-c-net/ to work out how to use it and I get the following code:
class clsIEquitable
{
public static void mainLaunch()
{
Person personOne = new Person() { Age = 6, Name = "Eva", Id = 1 };
Person personTwo = new Person() { Age = 7, Name = "Eva", Id = 1 };
//If Person didn't inherit from IEquatable, equals would point to different points in memory.
//This means this would be false as both objects are stored in different locations
//By using IEquatable on class it compares the objects directly
bool p = personOne.Equals(personTwo);
bool o = personOne.Id == personTwo.Id;
//Here is trying to compare and Object type with Person type and would return false.
//To ensure this works we added an overrides on the object equals method and it now works
object personThree = new Person() { Age = 7, Name = "Eva", Id = 1 };
bool p2 = personOne.Equals(personThree);
Console.WriteLine("Equatable Check", p.ToString());
}
}
public class Person : IEquatable<Person>
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public bool Equals(Person other)
{
if (other == null) return false;
return Id == other.Id;
}
//These are to support creating an object and comparing it to person rather than comparing person to person
public override bool Equals(object obj)
{
if (obj is Person)
{
Person p = (Person)obj;
return Equals(p);
}
return false;
}
public override int GetHashCode()
{
return Id;
}
}
My question is WHY would I use it? It seems like a lot of extra code to the simple version below (bool o):
//By using IEquatable on class it compares the objects directly
bool p = personOne.Equals(personTwo);
bool o = personOne.Id == personTwo.Id;
IEquatable<T> is used by generic collections to determine equality.
From this msdn article https://msdn.microsoft.com/en-us/library/ms131187.aspx
The IEquatable interface is used by generic collection objects such as Dictionary, List, and LinkedList when testing for equality in such methods as Contains, IndexOf, LastIndexOf, and Remove. It should be implemented for any object that might be stored in a generic collection.
This provides an added benefit when using structs, since calling the IEquatable<T> equals method does not box the struct like calling the base object equals method would.
This question already has answers here:
C# equality checking
(4 answers)
Closed 7 years ago.
I have an Object called User. Here's my class:
public class User
{
public string Name { get; set; }
public string IdNumber { get; set; }
public string OrgName { get; set; }
public string AcctCode { get; set; }
}
I create TWO objects that are exactly the same.
I want to see if their Equal, however, I get False back.
User user1 = new User()
{
Name = "Test User",
IdNumber = "1000354",
OrgName = "North",
AcctCode = "FTW"
};
User user2 = new User()
{
Name = "Test User",
IdNumber = "1000354",
OrgName = "North",
AcctCode = "FTW"
};
var doesEqual = user1.Equals(user2);
Console.WriteLine(doesEqual); // Returns FALSE
I also have TWO lists that have same objects in them, except for one.
When I do the Except, it doesn't want to work right and returns 131.
List<User> ListOne; // Contains 131 User objects
List<User> ListTwo; // Contains 130 User objects
var difference = ListOne.Except(ListTwo);
Console.WriteLine(difference); // Returns 131
What am I doing wrong??
By default, reference types will compare references. Meaning that your 2 separate instances, even though their fields have the same value, are different object and will compare as inequal. You can change this behavior by having your class implement IEquatable<T> to "teach" it how to compare any way you want.
A great example, that almost matches your usage, can be found on MSDN.
Class default equality criteria is by reference. It should return false.
You can override Equals method (and then you will have to implement GetHashCode) to whatever logic you want.
public override bool Equals(object obj)
{
if(!(obj is User))
{
return false;
}
User user= obj as User;
return user.Name == Name && user.IdNumber == IdNumber && user.OrgName == OrgName && user.AcctCode == AcctCode;
}
public override int GetHashCode()
{
return IdNumber.GetHashCode();
}
Despite the fact that all the properties of your objects have the same value, they are two completely different object. This user1 holds a reference to the heap for an object with some values. The same holds for user2. That being said this are two different references to the heap.
If you don't override the Equals method, then the equality is based on the references. So the objects are different, even when they have exactly the same values for all of their properties.
They are not equal because User is a class (i.e. a "reference type"). For reference types, .Equals compares reference equality, and the two instances user1 and user2 are two separate references.
The problem is this line:
user1.Equals(user2)
This line is asking if the user1 object the same as the user2 object. They have the same values but they are not the same object in memory. If you want to compare the values of these two objects you can override the Equals method like so:
public static override Equals(User user2)
{
return (this.Name == user2.Name &&
this.IdNumber == user2.IdNumber &&
this.AcctCode == user2.AcctCode &&
this.OrgName == user2.OrgName)
}
Your class User does not implement anything to tell the runtime when two objects are equal. The simpliest way to acchieve this is by overwriting the two Methods Equals and GetHashCode like this:
public override bool Equals(object obj)
{
User other = obj as User;
if( other == null ) return false;
return other.Name == Name && other.IdNumber == IdNumber && other.OrgName == OrgName && other.AcctCode == AcctCode;
}
public override int GetHashCode()
{
return IdNumber.GetHashCode();
}
I have two employee lists that I want to get only unique records from but this has a twist to it. Each list has an Employee class in it:
public class Employee
{
// I want to completely ignore ID in the comparison
public int ID{ get; set; }
// I want to use FirstName and LastName in comparison
public string FirstName{ get; set; }
public string LastName{ get; set; }
}
The only properties I want to compare on for a match are FirstName and LastName. I want to completely ignore ID in the comparison. The allFulltimeEmployees list has 3 employees in it and the allParttimeEmployees list has 3 employees in it. The first name and last name match on two items in the lists - Sally Jones and Fred Jackson. There is one item in the list that does not match because FirstName is the same, but LastName differs:
emp.id = null; // not populated or used in comparison
emp.FirstName = "Joe"; // same
emp.LastName = "Smith"; // different
allFulltimeEmployees.Add(emp);
emp.id = 3; // not used in comparison
emp.FirstName = "Joe"; // a match
emp.LastName = "Williams"; // not a match - different last name
allParttimeEmployees.Add(emp);
So I want to ignore the ID property in the class during the comparison of the two lists. I want to flag Joe Williams as a non-match since the last names of Smith and Williams in the two lists do not match.
// finalResult should only have Joe Williams in it
var finalResult = allFulltimeEmployees.Except(allParttimeEmployees);
I've tried using an IEqualityComparer but it doesn't work since it is using a single Employee class in the parameters rather than an IEnumerable list:
public class EmployeeEqualityComparer : IEqualityComparer<Employee>
{
public bool Equals(Employee x, Employee y)
{
if (x.FirstName == y.FirstName && x.LastName == y.LastName)
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(Employee obj)
{
return obj.GetHashCode();
}
}
How can I successfully do what I want and perform this operation? Thanks for any help!
Your idea of using the IEqualityComparer is fine, it's your execution that is wrong. Notably, your GetHashCode method.
public int GetHashCode(Employee obj)
{
return obj.GetHashCode();
}
IEqualityComparer defines both Equals and GetHashCode because both are important. Do not ignore GetHashCode when you implement this interface! It plays a pivotal role on equality comparisons. No, it is not an indication that two items are equal, but it is an indicator that two elements are not. Two equal elements must return the same hash code. If they do not, they cannot be considered equal. If they do, then they might be equal, and equality functions only then go on to explore Equals.
With your implementation delegating to the GetHashCode method of the actual employee object, you are relying upon the implementation that Employee class uses. Only if that implementation is overriden will it be useful for you, and only if it is using your key fields. And if it is, then it is very likely that you did not need to define your own external comparer in the first place!
Build a GetHashCode method that factors in your key fields and you will be set.
public int GetHashCode(Employee obj)
{
// null handling omitted for brevity, but you will want to
// handle null values appropriately
return obj.FirstName.GetHashCode() * 117
+ obj.LastName.GetHashCode();
}
Once you have this method in place, then use the comparer in your call to Except.
var comparer = new EmployeeEqualityComparer();
var results = allFulltimeEmployees.Except(allParttimeEmployees, comparer);
You can override Equals and GetHashCode in your Employees class.
For example,
public class Employee
{
// I want to completely ignore ID in the comparison
public int ID { get; set; }
// I want to use FirstName and LastName in comparison
public string FirstName { get; set; }
public string LastName { get; set; }
public override bool Equals(object obj)
{
var other = obj as Employee;
return this.FirstName == other.FirstName && this.LastName == other.LastName;
}
public override int GetHashCode()
{
return this.FirstName.GetHashCode() ^ this.LastName.GetHashCode();
}
}
I tested with the following data set:
var empList1 = new List<Employee>
{
new Employee{ID = 1, FirstName = "D", LastName = "M"},
new Employee{ID = 2, FirstName = "Foo", LastName = "Bar"}
};
var empList2 = new List<Employee>
{
new Employee { ID = 2, FirstName = "D", LastName = "M" },
new Employee { ID = 1, FirstName = "Foo", LastName = "Baz" }
};
var result = empList1.Except(empList2); // Contained "Foo Bar", ID #2.
your IEqualityComparer should work:
var finalResult = allFulltimeEmployees.Except(allParttimeEmployees, new EmployeeEqualityComparer());
Try implementing the IEquatable(T) interface for your Employee class. You simply need to provide an implementation for an Equals() method, which you can define however you want (i.e. ignoring employee IDs).
The IEquatable interface is used by generic collection objects such
as Dictionary, List, and LinkedList when testing
for equality in such methods as Contains, IndexOf, LastIndexOf, and
Remove. It should be implemented for any object that might be stored
in a generic collection.
Example implementation of the Equals() method:
public bool Equals(Employee other)
{
return (other != null) && (FirstName == other.FirstName) && (LastName == other.LastName);
}
It's not the most elegant solution, but you could make a function like so
public string GetKey(Employee emp)
{
return string.Format("{0}#{1}", emp.FirstName, emp.LastName)
}
and then populate everything in allFullTimeEmployees into a Dictionary<string, Employee> where the key of the dictionary is the result of calling GetKey on each employee object. Then you could loop over allParttimeEmployees and call GetKey on each of those, probing into the dictionary (e.g. using TryGetValue or ContainsKey), and taking whatever action was necessary on a duplicate, such as removing the duplicate from the dictionary.