i have this collection and i want to sort it based on rating then remove the duplicate name based on the nearest spelling distance using Levenshtein Algorithm..
here’s my code so far
and my expected result is
/*
* Expected result:
*
* Jjamppong v2
* Maggi
* Quick Chow
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Item> _items = new List<Item>();
_items.Add(new Item() { ItemID = 1, Name = "Jjamppong", Rating = 4 });
_items.Add(new Item() { ItemID = 2, Name = "Jjamppong v2", Rating = 6 });
_items.Add(new Item() { ItemID = 3, Name = "Jjamppong v3", Rating = 3 });
_items.Add(new Item() { ItemID = 4, Name = "Jjamppong v4", Rating = 2 });
_items.Add(new Item() { ItemID = 5, Name = "Maggi", Rating = 8 });
_items.Add(new Item() { ItemID = 6, Name = "Quick Chow", Rating = 1 });
_items.Add(new Item() { ItemID = 7, Name = "Maggi v2", Rating = 5 });
_items.OrderByDescending(i => i.Rating)
.Distinct(new DistinctByNameNearComparer<Item>())
.Select(i => i)
.ToList()
.ForEach(i =>
{
Console.WriteLine(i.Name);
});
Console.ReadKey();
/*
* Expected result:
*
* Jjamppong v2
* Maggi
* Quick Chow
*
*/
}
}
class Item
{
public int ItemID { get; set; }
public string Name { get; set; }
public int Rating { get; set; }
}
class DistinctByNameNearComparer : IEqualityComparer<Item>
{
public bool Equals(Item x, Item y)
{
int _distance = LevenshteinDistance.Compute(x.Name, y.Name);
int _maxLen = Math.Max(x.Name.Length, y.Name.Length);
return (_distance > (_maxLen - 5));
}
public int GetHashCode(Item obj)
{
return obj.GetHashCode();
}
}
class LevenshteinDistance
{
/// <summary>
/// Compute the distance between two strings.
/// </summary>
public static int Compute(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
}
}
i got an error here
_items.OrderByDescending(i => i.Rating)
.Distinct(new DistinctByNameNearComparer<Item>())
.Select(i => i)
.ToList()
.ForEach(i =>
{
Console.WriteLine(i.Name);
});
any help would be appreciated.
ANSWER:
class DistinctByNameNearComparer : IEqualityComparer<Item>
{
public bool Equals(Item x, Item y)
{
int _distance = LevenshteinDistance.Compute(x.Name, y.Name);
int _maxLen = Math.Max(x.Name.Length, y.Name.Length);
bool _comp = _distance < 4;
return _comp;
}
public int GetHashCode(Item obj)
{
return 1;
}
}
I suppose you’re receiving Compiler Error CS0308, saying
So the correct linq would be:
while you specify
The error is that
DistinctByNameNearCompareris not generic, so you cannot specify a type parameter for it. Compiler infers from_items.OrderByDescending(i => i.Rating)that the argument forDistinctshould be of typeIEqualityComparer<Item>and you’re expected to specify it. However yourDistinctByNameNearCompareris declared asthat is, it really is
IEqualityComparer<Item>. The only thing you need to do is to write