1

How can I prevent adding duplicate links from Clipboard to ListBox?

Here's my codes.

I used Regex so that I can easily add if the Clipboard contains only URLs

private void AddLinks()
{
    string[] linkItems = Clipboard.GetText().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
    Regex regURL = new Regex("https:(.*)", RegexOptions.Compiled | RegexOptions.Multiline);

    foreach (string link in linkItems)
    {
        MatchCollection url = regURL.Matches(link);
        LIST_URL.BeginUpdate();
        foreach (Match m in url)
        {
            LIST_URL.Items.Add(m);
        }
        LIST_URL.EndUpdate();
    }
}
zackmark15
  • 657
  • 6
  • 12
  • Can you explain your problem? Your question is really unclear. – Gusman Jun 27 '20 at 16:46
  • My question there is how I can avoid duplicate items in Listbox? Everytime I add new link item. it must check if the link is already exist in listbox – zackmark15 Jun 27 '20 at 17:18
  • Well, you have answered yourself: check if it is already in the list and add it only if it is not. – Gusman Jun 27 '20 at 17:20
  • The Regex pattern will get the valid Urls of `https` scheme only. Addresses like `www.x.net`, `google.com`, `ftp://...`, ..etc. will be ignored. Is that what you want? Otherwise, check [this](https://stackoverflow.com/q/161738/10216583) post for more Regex patterns. –  Jun 27 '20 at 18:25
  • 1
    No it's not about regex. It's about avoiding duplicate items. I just put the regex just in case someone will ask. I'm fine with that regex. because I have only specific link to load not all. – zackmark15 Jun 27 '20 at 19:06

2 Answers2

1

Using Regex and the given pattern, to get Urls from the Clipboard if any, and insert the distinct Urls into a ListBox:

private void AddLinks() =>
    LIST_URL.Items.AddRange(
        Regex.Matches(Clipboard.GetText(), @"https:(.*)*", 
            RegexOptions.Multiline | RegexOptions.IgnoreCase)
        .Cast<Match>()
        .Where(m => !LIST_URL.Items.Cast<string>()
        .Any(item => item.Equals(m.Value, StringComparison.InvariantCultureIgnoreCase)))
        .Select(m => m.Value)
        .ToArray()
        );

Also, you might want to try Uri.TryCreate method:

private void AddLinks() =>
    LIST_URL.Items.AddRange(Clipboard.GetText()
            .Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
            .Where(line => Uri.TryCreate(line, UriKind.Absolute, out Uri uri)
            && uri != null && uri.Scheme == Uri.UriSchemeHttps
            && !LIST_URL.Items.Cast<string>()
            .Any(item => line.Equals(item, StringComparison.InvariantCultureIgnoreCase)))
            .ToArray());

In both code snippets, the Enumerable.Any method in the .where scope excludes the duplicate Urls from the Clipboard and they - if any - won't be added to the list.

  • 1
    Wow this is what I'm looking for. I'm gonna try it now Thank you so much – zackmark15 Jun 28 '20 at 10:50
  • 1
    May I ask one more time? how I can use it for adding multiple files? I'm using it now for other codes. but can't figure out for adding files from local – zackmark15 Jun 28 '20 at 23:24
  • 1
    Sure. Something like: `listBox1.Items.AddRange(localFilesArray.Where(f => !listBox1.Items.Cast().Any(item => item.Equals(f, StringComparison.InvariantCultureIgnoreCase))).ToArray());` –  Jun 29 '20 at 00:36
  • 1
    It worked again :) thank you very much. I don't need to use my old class to remove duplicates. this is much easier – zackmark15 Jun 29 '20 at 00:51
  • Hello again @JQSOFT I wanna ask how to use it for adding listview subitems? I'm currently using your code on my listbox and now my problem is for listview item. I want to prevent adding multiple item – zackmark15 Jul 05 '20 at 08:07
  • @zackmark15 Hello there!. For `ListView` do something like: `lvw.Items.AddRange(itemsToAddStringArray.Where(x => lvw.FindItemWithText(x, true, 0) == null).Select(x => new ListViewItem(new string[] { x, "sub1", "sub2", "sub..." })).ToArray());` –  Jul 05 '20 at 09:12
  • @zackmark15 I pasted in your new question. You don't wait Mr. Zack. –  Jul 05 '20 at 10:13
1

Thank you @jQSOFT here's the final fixed codes. it worked 100%.

    private void AddLinks()
    {
        lbURL.Items.AddRange(Regex.Matches(Clipboard.GetText(), @"https?://www.viu.com/(.*)*",
            RegexOptions.Multiline | RegexOptions.IgnoreCase)
            .Cast<Match>()
            .Where(m => !lbURL.Items.Cast<string>()
            .Any(item => item.Equals(m.Value, StringComparison.InvariantCultureIgnoreCase)))
            .Select(m => m.Value)
            .ToArray());
    }

Another fixed by @jQSOFT maybe might help others too. Preventing duplicate when adding new items into listbox

 using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Filter = "m3u8 File(*.m3u8)|*.m3u8";
                ofd.RestoreDirectory = true;
                ofd.Multiselect = true;

                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    string[] files = ofd.FileNames;

                    List_URL.BeginUpdate();
                    List_URL.Items.AddRange
                                (files.Where(f => 
                                !List_URL.Items.Cast<string>().Any(item => 
                                item.Equals(f, StringComparison.InvariantCultureIgnoreCase))).ToArray());
                    List_URL.EndUpdate();
                }
            } 
zackmark15
  • 657
  • 6
  • 12