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  |        |         |
|______|_________|________|_________|
3
  • What do you do with ID? Commented Feb 17, 2016 at 8:57
  • 1
    how should categorized array look like? Commented Feb 17, 2016 at 8:57
  • Updated the question to clarify output format Commented Feb 17, 2016 at 9:01

4 Answers 4

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>');

Sign up to request clarification or add additional context in comments.

6 Comments

Much more elegant than mine :)
nice logic.. can we add the duplicate filter, for example BD-2 is repeated
and what is with values like SSNC-1 and SSNC/1? are they equal?
Good point, yes they are equal just that the inputter did not follow the right delimiter.. so they should be filtered as well.
and what should be the wanted style, non character, - or /?
|
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

6 Comments

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'];
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. :)
Can we filter duplicates in sortedBugs array generation itself?
Yes. I have changed the code above and we just use a set now in the first instance.
Logic is failing if the token and number has no seperator. eg: SSNC1. regexp needed the following change: match = bug.match(/([a-zA-Z]+)[-/]?.*/);
|
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 );

5 Comments

thanks, this works but includes only numbers in output array but we need the complete bugID with number
@sudheerg Check now, added whole value in the output
works well, just that we need duplicate filter and HTML output in table format
@sudheerg removed duplicates, check now
@sudheerg as far as tabular format is concerned, there are various examples stackoverflow.com/questions/18395976/…, stackoverflow.com/questions/1051061/…, stackoverflow.com/questions/18393860/…
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"
  ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.