【问题标题】:JavaScript to categorize array elements and output as HTMLJavaScript 对数组元素进行分类并输出为 HTML
【发布时间】:2016-05-28 20:53:48
【问题描述】:

我们有一个bugs = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10'] 格式的数组。

您可以看到它有 4 种不同的错误类型/令牌(BD、SSNC、RI 和 RC) - 将来可能会扩展。标记和 ID 号分隔符可以是 '-' 或 '/' 或什么都没有(例如:regexp match[-/]?),即数组可以是

= ['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']

现在尝试构建一个简单的 JavaScript 函数,该函数可以根据标记类型将元素分类为单独的数组,然后输出一个带有 bugtoken 类型的简单 HTML 表作为列标题。

对于bugs = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2', 'RC-10']的数组。`

输出应如下所示:

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

【问题讨论】:

  • 你用ID做什么?
  • 分类数组应该是什么样子的?
  • 更新了问题以阐明输出格式

标签: javascript


【解决方案1】:

我建议使用对象与匹配的标识符进行分组。

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

更新,结果带有不同的令牌和 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>');

【讨论】:

  • 比我的优雅多了:)
  • 很好的逻辑..我们可以添加重复过滤器吗,例如重复BD-2
  • SSNC-1SSNC/1 这样的值是什么?他们是平等的吗?
  • 好点,是的,它们是相等的,只是输入者没有遵循正确的分隔符......所以它们也应该被过滤掉。
  • 什么应该是想要的风格,非字符,-/
【解决方案2】:
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);});
}

现在,sortedBugs 有四个条目,每个条目都包含相应错误的数组。所以,sortedBugs['BD'] 只有 'BD-2',而 sortedBugs['SSNC'] 有 'SSNC-1' 和 'SSNC-3'。

编辑:四个非常相似的解决方案,很好。 :D

另一个编辑:现在使用集合不再有重复的条目

【讨论】:

  • 完美运行。只是没有过滤掉重复项。例如,如果数组具有相同令牌类型的重复项,我们需要能够跳过它.. 例如:bugs = ['BD-2', 'SSNC-1', 'SSNC-3', 'RI-2 '、'RC-10'、'BD-2'、'SSNC-1'、'SSNC-3'、'RI-2'、'RC-10'];
  • 你是对的。这可以通过使用 (new Set(sortedBugs[x])) 而不是 sortedBugs[x] 轻松解决。您也可以使用 (new Set(sortedBugs[x])).forEach(.) 等 :)
  • 我们可以在 sortedBugs 数组生成本身中过滤重复项吗?
  • 是的。我已经更改了上面的代码,我们现在只是在第一个实例中使用了一个集合。
  • 如果令牌和数字没有分隔符,则逻辑失败。例如:SSNC1。正则表达式需要以下更改: match = bug.match(/([a-zA-Z]+)[-/]?.*/);
【解决方案3】:

假设令牌名称只能包含字母(或数字后跟字母,如 2BD)

试试

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

【讨论】:

【解决方案4】:

问题已得到解答,但我想分享一个不同的解决方案。

我最近创建了一个在 JavaScript 中进行数组分类的库,名为 categorize

以下是使用它的解决方案:

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

bugsCategorized 变量将包含此对象:

{
  "BD": [
    "BD-2"
  ],
  "SSNC": [
    "SSNC-1",
    "SSNC-3"
  ],
  "RI": [
    "RI-2"
  ],
  "RC": [
    "RC-10"
  ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 2020-06-24
    • 2017-11-13
    • 1970-01-01
    相关资源
    最近更新 更多