繁体   English   中英

确认文档的出现次数

[英]Confirm number of occurrences of a document

我在创建一个程序时遇到了很大困难,该程序根据我设置的规则检查文档的出现次数。 在正则表达式的帮助下,我检查了一些字段,如果存在特定字段,我可以计算它的出现次数,或者我创建一个更深的扫描。 这有点令人困惑,我不确切知道如何解释。

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

我有以下数组:

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

这是欲望输出:

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

要做到这一点,我需要做一些检查,所以我想出了以下'MAP':

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

你可能喜欢这样。 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>"); 

所以现在我修改了代码以使用无限制的嵌套属性。 我不得不使用我的两个发明对象方法Object.prototype.getNestedValue()Object.prototype.setNestedValue() ,它们用于通过dynamicaly提供的参数访问和设置/修改嵌套对象属性及其值。 提供的最后一个参数是要获取或设置的值。 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>"); 

这不是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
      }
   }
}

在这里演示
正则表达式演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM