{"id":66163,"date":"2006-10-27T22:36:00","date_gmt":"2006-10-27T22:36:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/10\/27\/how-can-i-delete-duplicate-items-from-an-array\/"},"modified":"2006-10-27T22:36:00","modified_gmt":"2006-10-27T22:36:00","slug":"how-can-i-delete-duplicate-items-from-an-array","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-delete-duplicate-items-from-an-array\/","title":{"rendered":"How Can I Delete Duplicate Items From an Array?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I delete duplicate items from an array?<BR><BR>&#8212; WR<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, WR. You know, if Microsoft has a weakness \u2013 and we\u2019re not saying that it does, we\u2019re just saying <I>if<\/I> it does \u2013 it\u2019s this: we never make mistakes. (What\u2019s that? What about Windows ME? That\u2019s a weird name; couldn\u2019t possibly be one of our products.) <\/P>\n<P>Take arrays, for example. When someone at Microsoft creates an array it has <I>exactly <\/I>the right items in it; no more, no less. And that\u2019s a bit of a problem: because our arrays are always perfect it never occurred to us to come up with an easy way to delete items from an array. After all, if you create a perfect array right off the bat then why would you ever need to delete anything from that array?<\/P>\n<P>Of course, we also recognize that not everyone has a spotless record of success after success like we do. (Pardon? Microsoft Bob? No, sorry; never heard of him. Do you know what department he works in here?) Because of that, we <I>do<\/I> have workarounds for people who end up with duplicate items in their arrays. Can you delete duplicate items from an array? Sure. The process is a bit convoluted, but it\u2019ll work.<\/P>\n<P>Let\u2019s show you a script that deletes duplicate items from an array named arrItems, then see if we can explain how it works:<\/P><PRE class=\"codeSample\">Set objDictionary = CreateObject(&#8220;Scripting.Dictionary&#8221;)<\/p>\n<p>arrItems = Array(&#8220;a&#8221;,&#8221;b&#8221;,&#8221;b&#8221;,&#8221;c&#8221;,&#8221;c&#8221;,&#8221;c&#8221;,&#8221;d&#8221;,&#8221;e&#8221;,&#8221;e&#8221;,&#8221;e&#8221;)<\/p>\n<p>For Each strItem in arrItems\n    If Not objDictionary.Exists(strItem) Then\n        objDictionary.Add strItem, strItem   \n    End If\nNext<\/p>\n<p>intItems = objDictionary.Count &#8211; 1<\/p>\n<p>ReDim arrItems(intItems)<\/p>\n<p>i = 0<\/p>\n<p>For Each strKey in objDictionary.Keys\n    arrItems(i) = strKey\n    i = i + 1\nNext<\/p>\n<p>For Each strItem in arrItems\n    Wscript.Echo strItem\nNext\n<\/PRE>\n<P>As you can see, things start out in fairly straightforward fashion: in line 1 we simply create an instance of the <B>Scripting.Dictionary<\/B> object. (<I>Why<\/I> do we create a Dictionary object? Sit tight; we\u2019ll explain that in a minute.) We then use this line of code to create an array named arrItems, an array that \u2013 alas \u2013 includes a bunch of duplicate items:<\/P><PRE class=\"codeSample\">arrItems = Array(&#8220;a&#8221;,&#8221;b&#8221;,&#8221;b&#8221;,&#8221;c&#8221;,&#8221;c&#8221;,&#8221;c&#8221;,&#8221;d&#8221;,&#8221;e&#8221;,&#8221;e&#8221;,&#8221;e&#8221;)\n<\/PRE>\n<P>As we intimated earlier, there really is no way \u2013 at least no simple, intuitive way \u2013 to delete items from an array, let alone to detect duplicate items within an array. Therefore we\u2019re going to go a different route. What we decided to do here is take the items in the array and copy them into a Dictionary; we\u2019re going to do that because it <I>is<\/I> possible to prevent duplicate items from being entered into a Dictionary. Once the Dictionary has been populated we\u2019ll redimension our array and then (in essence) export the items in the Dictionary back to the array. Like we said, it\u2019s a bit convoluted, but the net effect is what we\u2019re looking for: when we\u2019re all done the array arrItems will contain only unique values. No more duplicates.<\/P>\n<P>Of course, all that hinges on us first getting the items in the array into the Dictionary. To do that we begin by setting up a For Each loop that loops through each and every item in the array:<\/P><PRE class=\"codeSample\">For Each strItem in arrItems\n<\/PRE>\n<P>Inside that loop we then use this line of code to determine whether the array item has already been added to the Dictionary:<\/P><PRE class=\"codeSample\">If Not objDictionary.Exists(strItem) Then\n<\/PRE>\n<P>It\u2019s kind of crazy syntax, but <B>If Not objDictionary.Exists(strItem) Then<\/B> can be read like this: \u201cIf the array item does not already exist in the Dictionary then do the following.\u201d And what <I>is<\/I> the following? This line of code, which adds the array item to the Dictionary, using the same value for both the Dictionary key and item:<\/P><PRE class=\"codeSample\">objDictionary.Add strItem, strItem\n<\/PRE>\n<TABLE id=\"EGE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. If you aren\u2019t familiar with the Dictionary object, or with terminology like <I>key<\/I> and <I>item<\/I>, then check out <A href=\"http:\/\/null\/technet\/scriptcenter\/guide\/sas_scr_ildk.mspx\"><B>this section<\/B><\/A> of the <I>Microsoft Windows 2000 Scripting Guide <\/I>or the Sesame Script article title, appropriately, <A href=\"http:\/\/null\/technet\/scriptcenter\/resources\/begin\/ss0906.mspx\"><B>The Dictionary Object<\/B><\/A>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>That\u2019s fine, but what if the item <I>does<\/I> exist in the Dictionary? No problem; in that case we simply loop around and tackle the next item in the array.<\/P>\n<P>Let\u2019s take a brief timeout to show you this works. The first item in our array is <I>a<\/I>. When we check the Dictionary the first time through the loop, we won\u2019t find a Dictionary key equal to <I>a<\/I>. Therefore, we add <I>a<\/I> to the Dictionary. We then loop around and repeat this process, this time with item <I>b<\/I>. That makes sense, right?<\/P>\n<P>Now, notice that the third item is the array is also a <I>b<\/I>, a duplicate item. What happens when we encounter this duplicate item on our third time through the loop? Nothing; because <I>b<\/I> is already in the Dictionary we won\u2019t add a second instance of <I>b<\/I>. (Actually we <I>can\u2019t<\/I> add a second instance of <I>b<\/I>; the Dictionary object doesn\u2019t allow duplicate keys.) Instead, we simply loop around and repeat this process with the fourth item in the array.<\/P>\n<P>Etc.<\/P>\n<P>When we\u2019re all done we\u2019ll have a Dictionary containing the following keys:<\/P><PRE class=\"codeSample\">a\nb\nc\nd\ne\n<\/PRE>\n<P>Those are your unique items right there, WR, which means you could simply work with the Dictionary object at this point. Just for the heck of it, though, let\u2019s talk about how you could reconfigure the array arrItems so that it contains just those 5 values. <\/P>\n<P>In order to reconfigure arrItems we first need to redimension the array; that is, we need to reset arrItems so that it will hold only as many items as we have in the Dictionary. To do that we first use this line of code to determine the number of items in the Dictionary, minus 1:<\/P><PRE class=\"codeSample\">intItems = objDictionary.Count &#8211; 1\n<\/PRE>\n<TABLE id=\"EQG\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. Why \u201cminus 1?\u201d Well, when you redimension an array you must specify the index number for the last allowable item. The first item in an array is always given the index number 0; that means that, in an array with 5 items, the last item will have an index number of 4 (the total number of items minus 1). Thus we take total number of items and subtract 1; that gives us the index number that will be assigned to the last item in the array.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After assigning the variable intItems the number of items in the Dictionary (that is, the Dictionary <B>Count<\/B>) minus 1, we then use this line of code to redimension the array arrItems and, while we\u2019re at it, delete all the existing data in the array:<\/P><PRE class=\"codeSample\">ReDim arrItems(intItems)\n<\/PRE>\n<P>In turn, that gives us an empty array that has reserved spots for 5 values. Now all we have to do is fill each of those 5 spots.<\/P>\n<P>Is that going to be hard? No, not really. After assigning the value 0 to a counter variable named <I>i<\/I> we set up a For Each loop to loop through each of the keys in the Dictionary:<\/P><PRE class=\"codeSample\">For Each strKey in objDictionary.Keys\n    arrItems(i) = strKey\n    i = i + 1\nNext\n<\/PRE>\n<P>Inside that loop we assign the first item in the array (remember, the first item has an index number of 0) the value of the first key in the Dictionary. We then increment our counter variable by 1, loop around, and repeat the process, this time assigning the second item in the array (index number 1) the value of the second key in the Dictionary. We simply repeat this process until each key in the Dictionary has been assigned a spot in the array.<\/P>\n<P>Is that really going to work? You bet it will. But just in case you don\u2019t believe us, we\u2019ve tacked some code to the end of the script that echoes back all the items in the array arrItems. Here\u2019s what we get back when we execute that block of code:<\/P><PRE class=\"codeSample\">a\nb\nc\nd\ne\n<\/PRE>\n<P>Absolutely perfect. But, then again, what <I>else<\/I> would you expect from Microsoft?<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I delete duplicate items from an array?&#8212; WR Hey, WR. You know, if Microsoft has a weakness \u2013 and we\u2019re not saying that it does, we\u2019re just saying if it does \u2013 it\u2019s this: we never make mistakes. (What\u2019s that? What about Windows ME? That\u2019s a weird name; couldn\u2019t possibly [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[18,3,4,5],"class_list":["post-66163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-arrays-hash-tables-and-dictionary-objects","tag-scripting-guy","tag-scripting-techniques","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I delete duplicate items from an array?&#8212; WR Hey, WR. You know, if Microsoft has a weakness \u2013 and we\u2019re not saying that it does, we\u2019re just saying if it does \u2013 it\u2019s this: we never make mistakes. (What\u2019s that? What about Windows ME? That\u2019s a weird name; couldn\u2019t possibly [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=66163"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/66163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=66163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=66163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=66163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}