{"id":162,"date":"2008-11-19T19:23:06","date_gmt":"2008-11-19T19:23:06","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/2008\/11\/19\/analyzing-addresses-using-different-data-structures\/"},"modified":"2008-11-20T15:39:05","modified_gmt":"2008-11-20T15:39:05","slug":"analyzing-addresses-using-different-data-structures","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2008\/11\/19\/analyzing-addresses-using-different-data-structures\/","title":{"rendered":"Analyzing Addresses Using Different Data Structures"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>Recently, at MathWorks, <a href=\"https:\/\/blogs.mathworks.com\/seth\/\">Seth<\/a> decided to analyze the email domains for comments on his blog.  He had fun writing the code and posting it internally.  Within\r\n         a short period of time, several other solutions emerged, including one that takes advantage of a new feature in <a href=\"https:\/\/www.mathworks.com\/help\/relnotes\/index.html\">R2008b<\/a>: <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/matlab_prog\/brqqo5e-1.html\"><tt>containers.Map<\/tt><\/a>. Let's first check out the problem itself.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">List of email addresses<\/a><\/li>\r\n         <li><a href=\"#2\">Seth's Solution Using regexp and cellfun<\/a><\/li>\r\n         <li><a href=\"#5\">Dave's Solution using containers.Map<\/a><\/li>\r\n         <li><a href=\"#9\">What IS containers.Map?<\/a><\/li>\r\n         <li><a href=\"#10\">Steve's Solution Using hist and unique<\/a><\/li>\r\n         <li><a href=\"#15\">Loren's Solution Using strfind and accumarray<\/a><\/li>\r\n         <li><a href=\"#16\">Other Ways, Other Data Structures?<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>List of email addresses<a name=\"1\"><\/a><\/h3>\r\n   <p>Seth wanted to know how many comments on this blog came from each domain, e.g., each location after the <tt>'@'<\/tt> symbol.\r\n   <\/p>\r\n   <p>Here's a list of made up email addresses for comments that came to Seth.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s = {<span style=\"color: #A020F0\">'0123456789@uni.ac.za'<\/span>\r\n<span style=\"color: #A020F0\">'alphabet_a@yahoo.com'<\/span>\r\n<span style=\"color: #A020F0\">'alphabet_b@gmail.com'<\/span>\r\n<span style=\"color: #A020F0\">'alpahbet_c@hotmail.com'<\/span>\r\n<span style=\"color: #A020F0\">'dAlphabet@xyzabc.com'<\/span>\r\n<span style=\"color: #A020F0\">'e_alphabet@yahoo.co.in'<\/span>\r\n<span style=\"color: #A020F0\">'falphabet@gmail.com'<\/span>\r\n<span style=\"color: #A020F0\">'loren.shure@mathworks.com'<\/span>\r\n<span style=\"color: #A020F0\">'loren@mathworks.com'<\/span>\r\n<span style=\"color: #A020F0\">'alphabetG@hanme.com'<\/span>\r\n<span style=\"color: #A020F0\">'alphabetH@bname.com'<\/span>\r\n<span style=\"color: #A020F0\">'alphabet_I@yahoo.co.in'<\/span>\r\n<span style=\"color: #A020F0\">'andJ@gmail.com'<\/span>\r\n<span style=\"color: #A020F0\">'Khere@gmail.com'<\/span>\r\n<span style=\"color: #A020F0\">'L-Student@erau.edu'<\/span>\r\n<span style=\"color: #A020F0\">'M@gmx.de'<\/span>};<\/pre><h3>Seth's Solution Using regexp and cellfun<a name=\"2\"><\/a><\/h3>\r\n   <p>Seth first uses <tt>regexp<\/tt> to identify the locations of the <tt>'@'<\/tt> symbol in each address.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s1 = regexp(s,<span style=\"color: #A020F0\">'@[\\w.]+'<\/span>,<span style=\"color: #A020F0\">'match'<\/span>,<span style=\"color: #A020F0\">'once'<\/span>);<\/pre><p>Next Seth finds the unique domain names, and finds the length of the longest name (used later to help him print the results).<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">sunique = unique(lower(s1));\r\nn = cell(length(sunique),1);\r\nmx = max(cellfun(@length,sunique));<\/pre><p>Finally, Seth prints the results.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #0000FF\">for<\/span> i=1:length(sunique)\r\n    n{i} = length(strmatch(sunique{i},lower(s1)));\r\n    disp([<span style=\"color: #A020F0\">' '<\/span> sunique{i} repmat(<span style=\"color: #A020F0\">' '<\/span>,[1 mx-length(sunique{i})]) <span style=\"color: #0000FF\">...<\/span>\r\n        <span style=\"color: #A020F0\">'  '<\/span> num2str(n{i})])\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><pre style=\"font-style:oblique\"> @bname.com      1\r\n @erau.edu       1\r\n @gmail.com      4\r\n @gmx.de         1\r\n @hanme.com      1\r\n @hotmail.com    1\r\n @mathworks.com  2\r\n @uni.ac.za      1\r\n @xyzabc.com     1\r\n @yahoo.co.in    2\r\n @yahoo.com      1\r\n<\/pre><h3>Dave's Solution using containers.Map<a name=\"5\"><\/a><\/h3>\r\n   <p>The next solution I show is from <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/7649\">Dave Tarkowski<\/a>, and uses a <tt>containers.Map<\/tt> object.  Dave starts by adopting Seth's code to find the matches.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s1 = regexp(s,<span style=\"color: #A020F0\">'@[\\w.]+'<\/span>,<span style=\"color: #A020F0\">'match'<\/span>,<span style=\"color: #A020F0\">'once'<\/span>);<\/pre><p>Next, create an object of the class <tt>containers.Map<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">m = containers.Map<\/pre><pre style=\"font-style:oblique\">m = \r\n  containers.Map handle\r\n  Package: containers\r\n\r\n  Properties:\r\n        Count: 0\r\n      KeyType: 'char'\r\n    ValueType: 'any'\r\n<\/pre><p>And now loop through each domain, check if the domain name is already a key name.<\/p>\r\n   <p>If the key doesn't exist yet, create it and set its value to 1, otherwise increase the value of the existing key by 1.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #0000FF\">for<\/span> i = 1:length(s1)\r\n    <span style=\"color: #0000FF\">if<\/span> m.isKey(s1{i})\r\n        m(s1{i}) = m(s1{i}) + 1;\r\n    <span style=\"color: #0000FF\">else<\/span>\r\n        m(s1{i}) = 1;\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><p>Finally, print out the statistics.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\"><span style=\"color: #0000FF\">for<\/span> k = keys(m)\r\n    disp([k{1} <span style=\"color: #A020F0\">' '<\/span> num2str(m(k{1}))])\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><pre style=\"font-style:oblique\">@bname.com 1\r\n@erau.edu 1\r\n@gmail.com 4\r\n@gmx.de 1\r\n@hanme.com 1\r\n@hotmail.com 1\r\n@mathworks.com 2\r\n@uni.ac.za 1\r\n@xyzabc.com 1\r\n@yahoo.co.in 2\r\n@yahoo.com 1\r\n<\/pre><h3>What IS containers.Map?<a name=\"9\"><\/a><\/h3>\r\n   <p><tt>containers.Map<\/tt> is a data structure often called a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Hash_table\">hash table<\/a> or map. You could use a Java hash table previously if you were set up to work with Java in MATLAB.  Now you now longer need\r\n      to bridge the MATLAB-Java interface for this functionality.  The <tt>containers.Map<\/tt> class provides a memory-efficient implementation of this data structure.  While similar in feel to a MATLAB <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/struct.html\"><tt>struct<\/tt><\/a>, a containers.Map object does not limit the key (similar to the field of a <tt>struct<\/tt> to be a valid MATLAB identifier.  The key can instead be any one of the following:\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>    scalar integer (signed or unsigned)<\/li>\r\n         <li>    scalar single or double<\/li>\r\n         <li>    <tt>1xn<\/tt> character array, even with embedded spaces\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>And there are a handful of methods you can use on these objects.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">methods(m)<\/pre><pre style=\"font-style:oblique\">\r\nMethods for class containers.Map:\r\n\r\nMap          findobj      isKey        length       remove       values       \r\naddlistener  findprop     isvalid      lt           size         \r\ndelete       ge           keys         ne           subsasgn     \r\neq           gt           le           notify       subsref      \r\n\r\n<\/pre><h3>Steve's Solution Using hist and unique<a name=\"10\"><\/a><\/h3>\r\n   <p><a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/4537\">Steve Lord<\/a> came along with a different solution.  In his words:\r\n   <\/p>\r\n   <p><i>Rather than using <tt>regexp<\/tt> (since I can never remember the regular expression language) and <tt>cellfun<\/tt>, I used <tt>strtok<\/tt>, <tt>hist<\/tt> and a second <tt>unique<\/tt> call.<\/i><\/p>\r\n   <p>Split the addresses at the AT symbol<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[T, R] = strtok(s, <span style=\"color: #A020F0\">'@'<\/span>);<\/pre><p>Use the fact that <tt>unique<\/tt> gives you <tt>b<\/tt> and <tt>k<\/tt> such that <tt>b{k}<\/tt> == <tt>R<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[suffixes, ignore, k] = unique(lower(R));<\/pre><p>Use the fact that <tt>unique<\/tt> sorts its output as well as removing duplicates.  Send the relevant outputs to <tt>hist<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[counts, indices] = hist(k, unique(k));<\/pre><p>Print the results.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[suffixes, num2cell(counts.')]<\/pre><pre style=\"font-style:oblique\">ans = \r\n    '@bname.com'        [1]\r\n    '@erau.edu'         [1]\r\n    '@gmail.com'        [4]\r\n    '@gmx.de'           [1]\r\n    '@hanme.com'        [1]\r\n    '@hotmail.com'      [1]\r\n    '@mathworks.com'    [2]\r\n    '@uni.ac.za'        [1]\r\n    '@xyzabc.com'       [1]\r\n    '@yahoo.co.in'      [2]\r\n    '@yahoo.com'        [1]\r\n<\/pre><h3>Loren's Solution Using strfind and accumarray<a name=\"15\"><\/a><\/h3>\r\n   <p>I came late to the game on this one.  Before seeing any solutions except Seth's, I thought about using <tt>strfind<\/tt> to locate the domain, and <tt>accumarray<\/tt> to gather the data.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">inds = strfind(s,<span style=\"color: #A020F0\">'@'<\/span>);\r\nallSuffixes = cellfun(@(str,ind) str(ind:end), s, inds, <span style=\"color: #0000FF\">...<\/span>\r\n    <span style=\"color: #A020F0\">'UniformOutput'<\/span>, false);\r\n[uniqueSuffixes,ignore,uind] = unique(lower(allSuffixes));\r\n\r\n<span style=\"color: #228B22\">% I'd be remiss if there was no solution using accumarray<\/span>\r\ncounts = accumarray(uind,1,[length(uniqueSuffixes) 1]);\r\n[uniqueSuffixes num2cell(counts)]<\/pre><pre style=\"font-style:oblique\">ans = \r\n    '@bname.com'        [1]\r\n    '@erau.edu'         [1]\r\n    '@gmail.com'        [4]\r\n    '@gmx.de'           [1]\r\n    '@hanme.com'        [1]\r\n    '@hotmail.com'      [1]\r\n    '@mathworks.com'    [2]\r\n    '@uni.ac.za'        [1]\r\n    '@xyzabc.com'       [1]\r\n    '@yahoo.co.in'      [2]\r\n    '@yahoo.com'        [1]\r\n<\/pre><h3>Other Ways, Other Data Structures?<a name=\"16\"><\/a><\/h3>\r\n   <p>Yes, there are, no doubt, other ways to complete this same task, including some ideas for the counting such as those in <a href=\"https:\/\/blogs.mathworks.com\/loren\/2006\/12\/01\/let-me-count-the-ways\/\">this post<\/a>. Do you have other favorite ways to do this sort of task?  Besides <tt>containers.Map<\/tt>, what other data structures would you like to see in MATLAB?  As usual, please post your thoughts <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=162#respond\">here<\/a>.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_1aa576c44cb14f4bb572a687108b874b() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='1aa576c44cb14f4bb572a687108b874b ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 1aa576c44cb14f4bb572a687108b874b';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Loren Shure';\r\n        copyright = 'Copyright 2008 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n      \r\n-->\r\n<\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_1aa576c44cb14f4bb572a687108b874b()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.7<br><\/p>\r\n<\/div>\r\n<!--\r\n1aa576c44cb14f4bb572a687108b874b ##### SOURCE BEGIN #####\r\n%% Analyzing Addresses Using Different Data Structures\r\n% Recently, at MathWorks, <https:\/\/blogs.mathworks.com\/seth\/ Seth> decided\r\n% to analyze the email domains for comments on his blog.  He had fun\r\n% writing the code and posting it internally.  Within a short period of\r\n% time, several other solutions emerged, including one that takes advantage\r\n% of a new feature in \r\n% <https:\/\/www.mathworks.com\/help\/relnotes\/index.html R2008b>:\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/matlab_prog\/brqqo5e-1.html |containers.Map|>.\r\n% Let's first check out the problem itself.\r\n\r\n%% List of email addresses\r\n% Seth wanted to know how many comments on this blog came from each domain,\r\n% e.g., each location after the |'@'| symbol.\r\n%\r\n% Here's a list of made up email addresses for comments that came to Seth.\r\ns = {'0123456789@uni.ac.za'\r\n'alphabet_a@yahoo.com'\r\n'alphabet_b@gmail.com'\r\n'alpahbet_c@hotmail.com'\r\n'dAlphabet@xyzabc.com'\r\n'e_alphabet@yahoo.co.in'\r\n'falphabet@gmail.com'\r\n'loren.shure@mathworks.com'\r\n'loren@mathworks.com'\r\n'alphabetG@hanme.com'\r\n'alphabetH@bname.com'\r\n'alphabet_I@yahoo.co.in'\r\n'andJ@gmail.com'\r\n'Khere@gmail.com'\r\n'L-Student@erau.edu'\r\n'M@gmx.de'};\r\n\r\n%% Seth's Solution Using regexp and cellfun\r\n% Seth first uses |regexp| to identify the locations of the |'@'| symbol in\r\n% each address.\r\ns1 = regexp(s,'@[\\w.]+','match','once');\r\n\r\n%%\r\n% Next Seth finds the unique domain names, and finds the length of the\r\n% longest name (used later to help him print the results).\r\nsunique = unique(lower(s1));\r\nn = cell(length(sunique),1);\r\nmx = max(cellfun(@length,sunique));\r\n\r\n%% \r\n% Finally, Seth prints the results.\r\nfor i=1:length(sunique)\r\n    n{i} = length(strmatch(sunique{i},lower(s1)));\r\n    disp([' ' sunique{i} repmat(' ',[1 mx-length(sunique{i})]) ...\r\n        '  ' num2str(n{i})])\r\nend\r\n\r\n%% Dave's Solution using containers.Map\r\n% The next solution I show is from \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/7649 Dave Tarkowski>,\r\n% and uses a |containers.Map| object.  Dave starts by adopting Seth's code\r\n% to find the matches.\r\ns1 = regexp(s,'@[\\w.]+','match','once');\r\n%%\r\n% Next, create an object of the class |containers.Map|.\r\nm = containers.Map\r\n%%\r\n% And now loop through each domain, check if the domain name is already a\r\n% key name.\r\n%\r\n% If the key doesn't exist yet, create it and set its value to 1, otherwise\r\n% increase the value of the existing key by 1.\r\nfor i = 1:length(s1)\r\n    if m.isKey(s1{i})\r\n        m(s1{i}) = m(s1{i}) + 1;\r\n    else\r\n        m(s1{i}) = 1;\r\n    end\r\nend\r\n%%\r\n% Finally, print out the statistics.\r\nfor k = keys(m)\r\n    disp([k{1} ' ' num2str(m(k{1}))])\r\nend\r\n%% What IS containers.Map?\r\n% |containers.Map| is a data structure often called a\r\n% <http:\/\/en.wikipedia.org\/wiki\/Hash_table hash table> or map. You could\r\n% use a Java hash table previously if you were set up to work with Java in\r\n% MATLAB.  Now you now longer need to bridge the MATLAB-Java interface for\r\n% this functionality.  The |containers.Map| class provides a\r\n% memory-efficient implementation of this data structure.  While similar in\r\n% feel to a MATLAB \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2008b\/techdoc\/ref\/struct.html |struct|>,\r\n% a containers.Map object does not limit the key (similar to the field of\r\n% a |struct| to be a valid MATLAB identifier.  The key can instead be any \r\n% one of the following:\r\n% \r\n% *     scalar integer (signed or unsigned)\r\n% *     scalar single or double \r\n% *     |1xn| character array, even with embedded spaces\r\n%\r\n% And there are a handful of methods you can use on these objects.\r\nmethods(m)\r\n%% Steve's Solution Using hist and unique\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/authors\/4537 Steve Lord> \r\n% came along with a different solution.  In his words:\r\n% \r\n%\r\n% _Rather than using |regexp| (since I can never remember the regular\r\n% expression language) and |cellfun|, I used |strtok|, |hist| and a second \r\n% |unique| call._\r\n\r\n%%\r\n% Split the addresses at the AT symbol\r\n[T, R] = strtok(s, '@');\r\n%%\r\n% Use the fact that |unique| gives you |b| and |k| such that |b{k}| == |R|.\r\n[suffixes, ignore, k] = unique(lower(R));\r\n%%\r\n% Use the fact that |unique| sorts its output as well as removing\r\n% duplicates.  Send the relevant outputs to |hist|.\r\n[counts, indices] = hist(k, unique(k));\r\n%%\r\n% Print the results.\r\n[suffixes, num2cell(counts.')]\r\n\r\n%% Loren's Solution Using strfind and accumarray\r\n% I came late to the game on this one.  Before seeing any solutions except\r\n% Seth's, I thought about using |strfind| to locate the domain, and\r\n% |accumarray| to gather the data.\r\ninds = strfind(s,'@');\r\nallSuffixes = cellfun(@(str,ind) str(ind:end), s, inds, ...\r\n    'UniformOutput', false);\r\n[uniqueSuffixes,ignore,uind] = unique(lower(allSuffixes));\r\n\r\n% I'd be remiss if there was no solution using accumarray\r\ncounts = accumarray(uind,1,[length(uniqueSuffixes) 1]);\r\n[uniqueSuffixes num2cell(counts)]\r\n%% Other Ways, Other Data Structures?\r\n% Yes, there are, no doubt, other ways to complete this same task,\r\n% including some ideas for the counting such as those in\r\n% <https:\/\/blogs.mathworks.com\/loren\/2006\/12\/01\/let-me-count-the-ways\/ this post>.\r\n% Do you have other favorite ways to do this sort of task?  Besides\r\n% |containers.Map|, what other data structures would you like to see in\r\n% MATLAB?  As usual, please post your thoughts \r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=162#respond here>.\r\n\r\n##### SOURCE END ##### 1aa576c44cb14f4bb572a687108b874b\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      Recently, at MathWorks, Seth decided to analyze the email domains for comments on his blog.  He had fun writing the code and posting it internally.  Within\r\n         a short period of... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2008\/11\/19\/analyzing-addresses-using-different-data-structures\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/162"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=162"}],"version-history":[{"count":0,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/162\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=162"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=162"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=162"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}