[英]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.