Reputation: 727
Could someone give me LINQ code to avoid allowing duplicate items when adding new items into ListView
?
Here's my current code for adding items from clipboard with regex.
List<string> uri = new List<string>();
string URLPattern = cbRegEx.Text;
string cb = Clipboard.GetText();
uri.Clear();
MatchCollection mc = Regex.Matches(cb, URLPattern, RegexOptions.IgnoreCase);
foreach (Match m in mc)
{
uri.Add(m.Value);
}
LV_Url.BeginUpdate();
foreach (var Uri in uri)
{
ListViewItem lv = new ListViewItem();
lv.Text = (LV_Url.Items.Count + 1).ToString();
lv.SubItems.Add(GetUrlFileName(Uri));
lv.SubItems.Add(Uri);
LV_Url.Items.Add(lv);
LV_Url.AutoResizeColumn(1, ColumnHeaderAutoResizeStyle.ColumnContent);
}
LV_Url.EndUpdate();
Upvotes: 1
Views: 376
Reputation:
To get a distinct string collection from the Clipboard and insert the items into a ListView except the duplicates:
var urls = new List<string>();
//...
//get them from the Clipboard...
//...
//Add the new Urls only:
LV_Url.BeginUpdate();
LV_Url.Items.AddRange(
urls
.Distinct()
.Where(url => LV_Url.Items.Count == 0
|| LV_Url.FindItemWithText(url, true, 0) == null)
.Select((url, i) => new ListViewItem(new[]
{
(LV_Url.Items.Count + i + 1).ToString(),
GetUrlFileName(url),
url
}
)).ToArray());
//Optional to fit the contents...
LV_Url.Columns.Cast<ColumnHeader>().ToList().ForEach(c => c.Width = -2);
LV_Url.EndUpdate();
Or add from the Clipboard directly:
LV_Url.BeginUpdate();
LV_Url.Items.AddRange(
Regex.Matches(Clipboard.GetText(),
URLPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline)
.Cast<Match>().Select(m => m.Value) //Or some m.Groups[n].Value...
.Distinct()
.Where(url => LV_Url.Items.Count == 0
|| LV_Url.FindItemWithText(url, true, 0) == null)
.Select((url, i) => new ListViewItem(new[]
{
(LV_Url.Items.Count + i + 1).ToString(),
GetUrlFileName(url),
url
}
)).ToArray());
LV_Url.Columns.Cast<ColumnHeader>().ToList().ForEach(c => c.Width = -2);
LV_Url.EndUpdate();
Upvotes: 1
Reputation: 727
Finally thanks for all your answer. But this is what I used :) Thanks to @JQSOFT
LV_Url.BeginUpdate();
LV_Url.Items.AddRange(Regex.Matches(Clipboard.GetText(), URLPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline)
.Cast<Match>().Select(m => m.Value)
.Where(url => LV_Url.Items.Count == 0 || LV_Url.FindItemWithText(url, true, 0) == null)
.Select((url, i) => new ListViewItem(new[]
{
(LV_Url.Items.Count + i + 1).ToString(),
Util.GetUrlFileName(url),
url
})).ToArray());
LV_Url.EndUpdate();
Upvotes: 1
Reputation: 1398
Use HashSet<string>
instead of using List<string>
, it's going to ignore allowing duplicate value in the list.
HashSet<string> list = new HashSet<string>();
list.Add("duplicate");
list.Add("duplicate");
Console.WriteLine(list.Count);//output 1
Upvotes: 4
Reputation: 5861
You can use Distinct()
to remove dublicates
MatchCollection mc = Regex.Matches(cb, URLPattern, RegexOptions.IgnoreCase);
foreach (Match m in mc.Distinct())
{
uri.Add(m.Value);
}
Or
MatchCollection mc = Regex.Matches(cb, URLPattern, RegexOptions.IgnoreCase);
foreach (Match m in mc)
{
uri.Add(m.Value);
}
uri = uri.Distinct().ToList();
Upvotes: 1