3

we have an array of the format bugs = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10'].

You can see it has 4 different bug types/tokens (BD, SSNC, RI and RC) - this could expand in future. The token and ID Number separator can be a '-' or '/' or nothing (E.g: regexp match[-/]?) ie, the array can be

= ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10'] or
= ['BD-2', 'SSNC/1', 'SSNC-3', 'RI-2', 'RC/10'] or
= ['BD-2', 'SSNC-1', 'SSNC3', 'RI-2', 'RC10']

Now trying to build a Simple JavaScript function which can categorize the elements into separate arrays based on token type and then output a simple HTML table with bugtoken type as column headers.

For an array of bugs = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10'].`

Output should look like:

 ___________________________________
| BD      SSNC        RI      RC    |
|------+---------+--------+---------+
|BD-2  | SSNC-1, |   RI-2 |  RC-10  |
|      | SSNC-3  |        |         |
|______|_________|________|_________|
sudheer
  • 94
  • 9

4 Answers4

3

I suggest to use an object for grouping with the matched identifier.

var data = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10', 'BD-2', 'SSNC/1', 'SSNC/3', 'RI/1', 'RC/10', 'BD-2', 'SSNC-1', 'SSNC3', 'RI-2', 'RC10'],
    grouped = function (data) {
        var o = {};
        data.forEach(function (a) {
            var group = a.match(/^[a-zA-Z]+/);
            o[group] = o[group] || [];
            o[group].push(a);
        });
        return o;
    }(data);

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');

Update, result with distinct token and id.

var data = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10', 'BD-2', 'SSNC/1', 'SSNC/3', 'RI/1', 'RC/10', 'BD-2', 'SSNC-1', 'SSNC3', 'RI-2', 'RC10'],
    grouped = function (data) {
        var o = {}, r = {};
        data.forEach(function (a) {
            var group = a.match(/^[a-zA-Z]+/),
                number = a.match(/\d+$/);
            o[group] = o[group] || {};
            r[group] = r[group] || [];
            if (!(number in o[group])) {
                o[group][number] = r[group].push(a) - 1;
            }
            if (r[group][o[group][number]] !== a) {
                r[group][o[group][number]] = group + '-' + number;
            }
        });
        return r;
    }(data);

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1
bugs = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10'];

sortedBugs = [];

bugs.forEach(function(bug){
    match = bug.match(/([a-zA-Z]+)[ -/]{1}.*/);

    if(!sortedBugs[match[1]])
        sortedBugs[match[1]] = new Set();

    sortedBugs[match[1]].add(match[0]);
});

for(var x in sortedBugs)
{
    console.log("Bug Category '" + x + "':");

    sortedBugs[x].forEach(function(a) {console.log(a);});
}

Now, sortedBugs has four entries, each of which contains an array of the corresponding bugs. So, sortedBugs['BD'] has only 'BD-2', while sortedBugs['SSNC'] has 'SSNC-1' and 'SSNC-3'.

Edit: Four very similar solution, nices. :D

Another edit: now has no duplicate entries anymore by using a set

IceFire
  • 4,016
  • 2
  • 31
  • 51
  • Works perfect. just that duplicates are not filtered out. for example if the array has duplicates of the same token type, we need to be able to skip that.. eg: bugs = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10','BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10']; – sudheer Feb 17 '16 at 09:26
  • 1
    You are right. This can easily be solved by using (new Set(sortedBugs[x])) instead of sortedBugs[x]. You can also use (new Set(sortedBugs[x])).forEach(.) etc. :) – IceFire Feb 17 '16 at 09:30
  • Can we filter duplicates in sortedBugs array generation itself? – sudheer Feb 17 '16 at 09:35
  • Yes. I have changed the code above and we just use a set now in the first instance. – IceFire Feb 17 '16 at 09:40
  • Logic is failing if the token and number has no seperator. eg: SSNC1. regexp needed the following change: match = bug.match(/([a-zA-Z]+)[-/]?.*/); – sudheer Feb 17 '16 at 10:18
  • This will work, unless there is another a-zA-Z letter followed after SSNC. If there are only numbers, your regex is better, though, right. Do not forget to mark any answer as solution, when you consider your question answered, so that it will disappear as unanswered question at stackoverflow :) – IceFire Feb 17 '16 at 10:33
1

Assuming that token name can have only alphabets (or numbers followed by alphabets like 2BD)

try

var array = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10'];
var output = {};
array.forEach( function(value){ 

   var number = (value.match( /\d+/g)).pop(); 
   token = value.substring( 0, value.length - ( number.length ) ).replace(/[\W]/g,"");
   if ( !output[token] )
   {
      output[token] = [];
   }
   if ( output[token].indexOf( value ) == -1 )
   {
       output[token].push( value );
   } 
} );

console.table( output );
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • thanks, this works but includes only numbers in output array but we need the complete bugID with number – sudheer Feb 17 '16 at 09:53
  • @sudheerg Check now, added whole value in the output – gurvinder372 Feb 17 '16 at 09:55
  • works well, just that we need duplicate filter and HTML output in table format – sudheer Feb 17 '16 at 10:01
  • @sudheerg removed duplicates, check now – gurvinder372 Feb 17 '16 at 10:30
  • 1
    @sudheerg as far as tabular format is concerned, there are various examples http://stackoverflow.com/questions/18395976/how-to-display-a-json-array-in-table-format, http://stackoverflow.com/questions/1051061/convert-json-array-to-an-html-table-in-jquery, http://stackoverflow.com/questions/18393860/how-to-parse-a-json-list-like-this-and-display-its-elements-in-html – gurvinder372 Feb 17 '16 at 10:39
0

The question has been answered but I have a different solution I would like to share.

I recently created a library that does array categorization in JavaScript, called categorize.

Here is what would be the solution using it:

const { categorize } = require("categorize");

const bugTypes = ["BD", "SSNC", "RI", "RC"];

const bugs = ["BD-2", "SSNC-1", "SSNC-3", "RI-2", "RC-10"];

const bugsCategorized = categorize(bugs, bugTypes.map((bugType) => ({
  name: bugType,
  filter: (bug) => bug.startsWith(bugType)
})));

The bugsCategorized variable will contain this object:

{
  "BD": [
    "BD-2"
  ],
  "SSNC": [
    "SSNC-1",
    "SSNC-3"
  ],
  "RI": [
    "RI-2"
  ],
  "RC": [
    "RC-10"
  ]
}
Ghassen Rjab
  • 683
  • 7
  • 20