【问题标题】:Confirm number of occurrences of a document确认文档的出现次数
【发布时间】:2016-09-16 19:21:57
【问题描述】:

我在创建一个程序来根据我设置的规则检查文档的出现次数时遇到了巨大的困难。在正则表达式的帮助下,我检查了一些字段,如果存在特定字段,我可以计算它出现的次数,或者我创建更深入的扫描。有点混乱,不知道具体怎么解释。

我正在检查文本文件,但为了降低复杂性,我将使用数组。

我有以下数组:

let strings = [
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME2 ID: 10'
];

这是欲望输出:

{
  'NAME' :  { '12': 3 },
  'NAME2':  { '10': 1 }
}

为了实现这一点,我需要做一些检查,所以我想出了以下“地图”:

let patterns = [
  {
    'pattern': 'COMPANY:\\s*?([\\w]+)\\s',
    'modifier': ''
  },
  {
    'pattern'  : 'ID:\\s*?(\\d{2})\\s*',
    'modifier' : ''
  }
];

我很难创建伪代码,我知道这是可以递归完成的,但我被卡住了。最大的问题是因为嵌套,我可以嵌套几级,不一定是两级。

在过去的几个小时里,我创建了以下代码:

'use strict';

let patterns = [
  {
    'pattern': 'COMPANY:\\s*?([\\w]+)\\s',
    'modifier': ''
  },
  {
    'pattern'  : 'ID:\\s*?(\\d{2})\\s*',
    'modifier' : ''
  }
];

let strings = [
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME  ID: 12',
  'COMPANY: NAME2 ID: 10'
];

var _data = {};
for (let string of strings) {

  var root = _data;

  for (let i = 0, length = patterns.length; i < length; i++) {

    let item   = patterns[i];

    let regex  = new RegExp(item.pattern, item.modifier);
    let result = regex.exec(string);

    if (i < patterns.length -1) {
      root = root[result[1]] = {};
    } else {
      root = root[result[1]] = 1;
    }
  }
}

document.body.innerHTML = JSON.stringify({_data});

现在我正在尝试获取最后一部分,计算出现的次数,这真是令人头疼。也许递归或生成器可以解决这个问题。

更新 -

理解应该与 3、4、5 对象一起使用是很重要的。示例:

let patterns = [
  {
    'pattern': 'COMPANY:\\s*?([\\w]+)\\s',
    'modifier': ''
  },
  {
    'pattern'  : 'ID:\\s*?(\\d{2})\\s*',
    'modifier' : ''
  },
  {
    'pattern'  : 'SOMETHING:\\s*?(\\d+)\\s*',
    'modifier' : ''
  }
];

let strings = [
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME  ID: 12 SOMETHING: 1010',
  'COMPANY: NAME2 ID: 10 SOMETHING: 1010'
];

输出应该是:

{
  'NAME': {
    '12': {
      '1010': 3
    }
  },
  'NAME2': {
    '10': {
      '1010': 1
    }
  }
}

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    你可以这样做。 Array.prototype.reduce() 非常适合这些工作。

    var strings = [
      'COMPANY: NAME  ID: 12',
      'COMPANY: NAME  ID: 12',
      'COMPANY: NAME  ID: 12',
      'COMPANY: NAME2 ID: 10'
    ],
    
    reduced = strings.reduce((p,c) => {var co = c.match(/\w+(?=\s*ID)/)[0],
                                       id = c.match(/\d+$/)[0];
                                       p[co] ? p[co][id]++ : p[co] = {[id]:1};
                                       return p},{});
    document.write("<pre>" +JSON.stringify(reduced,null,2) + "</pre>");

    所以现在我修改了代码以使用无限的嵌套属性。我必须使用my invention 对象方法中的两个Object.prototype.getNestedValue()Object.prototype.setNestedValue(),它们用于通过动态提供的参数访问和设置/修改嵌套对象属性及其值。提供的最后一个参数是要获取或设置的值。 previopus 参数是嵌套属性。对于这些用例,它们是非常方便的方法。就这样吧

    Object.prototype.getNestedValue = function(...a) {
      return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
    };
    Object.prototype.setNestedValue = function(...a) {
      a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
                                                                           : (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]),
                                                                                     this[a[0]].setNestedValue(...a.slice(1)))
                          : this[a[0]] = a[1];
      return this;
    };
    
    
    var strings = [
      'COMPANY: NAME  ID: 12 SOMETHING: 1010 MORE: 857',
      'COMPANY: NAME  ID: 12 SOMETHING: 1010 MORE: 857',
      'COMPANY: NAME  ID: 12 SOMETHING: 1010 MORE: 857',
      'COMPANY: NAME2 ID: 10 SOMETHING: 1010 MORE: 333'
    ],
    
    reduced = strings.reduce((p,c) => {var props = c.match(/(?::\s*)[^\s]+/g).map(e => e.split(":")[1].trim()),
                                           value = p.getNestedValue(...props);
                                       !!value ? p.setNestedValue(...props,++value) : p.setNestedValue(...props,1);
                                       return p},{});
    
    document.write("<pre>" + JSON.stringify(reduced,null,2) + "</pre>");

    【讨论】:

    • @D_REIS 刚刚看到...没有什么大不了的可以以同样的方式完成。我会相应地修改我的答案。
    • 很难吧?我正在尝试至少 2 天。
    • @D_REIS 既然你说它是无限的嵌套对象,它“有点”复杂,但我同意了。我会想出一个答案。
    • @D_REIS 是的,这正是我现在正在做的事情
    • @vp_arth:获取要在我们要构建的嵌套结构中使用的属性根本不是 OP 的主要问题。问题是一旦你拥有这些属性“不管”它们有多少,就动态地构建嵌套结构。 OP 可以轻松地使用任何正则表达式将源文本拆分为他想要的属性集,剩下的就由这个代码完成。
    【解决方案2】:

    它不是 ES6 的解决方案,但它相对容易理解:

    var strings = [
      'COMPANY: NAME  ID: 12 SOMETHING: 1010',
      'COMPANY: NAME  ID: 12 SOMETHING: 1010',
      'COMPANY: NAME  ID: 12 SOMETHING: 1010',
      'COMPANY: NAME2 ID: 10 SOMETHING: 1010',
      'COMPANY: NAME2 ID: 11 SOMETHING: 1010'
    ];
    
    var output = {};
    
    for (var i = 0; i < strings.length; i++) {
        var line = strings[i];
        // regex to extract only the values from the current line
        // e.g (NAME, 12, 1010)
        var matches = line.match(/[^\s:]+(?=\s+[^:]+:|$)/g);
        var currentObj = output;
        for (var y = 0; y < matches.length; y++) {
            var match = matches[y];
            var value = currentObj[match];
    
            // if the value is not the deepest field, 
            //   then create the deeper object to hold the next iteration's values
            // else if it is the deepest field then store the appropriate count
            currentObj[match] = y < matches.length - 1
                                  ? value || {}
                                  : value ? value + 1 : 1;
    
            // set up for the next iteration
            currentObj = currentObj[match];
        }
    }
    
    console.log(output);
    

    输出:

    {
       'NAME':{
          '12':{
             '1010':3
          }
       },
       'NAME2':{
          '10':{
             '1010':1
          },
          '11':{
             '1010':1
          }
       }
    }
    

    Demo here.
    Regex demo.

    【讨论】:

      【解决方案3】:
      'use strict';
      
          let patterns = [
            {
              'pattern': 'COMPANY:\\s*?([\\w]+)\\s',
              'modifier': ''
            },
            {
              'pattern'  : 'ID:\\s*?(\\d{2})\\s*',
              'modifier' : ''
            },
            {
              'pattern'  : 'EFD:\\s*?(\\d{2})\\s*',
              'modifier' : ''
            }
          ];
      
      let strings = [
        'COMPANY: NAME  ID: 12 SOMETHING: 1010',
        'COMPANY: NAME  ID: 12 SOMETHING: 1010',
        'COMPANY: NAME  ID: 12 SOMETHING: 1010',
        'COMPANY: NAME2 ID: 10 SOMETHING: 1010'
      ];
      
          var result = {};
          strings.forEach(function(value, index) {
              var split = value.replace(/ +(?= )/g,'').split(" ");
            var name = split[1];
            var correspondingValue = split[3];
            var efd = split[5];
      
      
            if (!(result[name])) {
              result[name] = {};
              result[name][correspondingValue] = {};
              result[name][correspondingValue][efd] = 1;
            } else {
              result[name][correspondingValue][efd]++;
            }
      
          });
      
          document.body.innerHTML = JSON.stringify(result);
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      相关资源
      最近更新 更多