Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
407 views
in Technique[技术] by (71.8m points)

javascript - Confirm number of occurrences of a document

I'm having a huge difficulty in creating a program to check the number of occurrences of a document based on rules set by me. With the help of regex, I check some fields, and if a particular field exists , I can count the number of occurrences of it, or I create a deeper scan. It's a little confusing, and I do not know exactly how to explain.

I 'm checking text files, but to reduce the complexity , I will use arrays.

I have the following array:

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

And this is the desire output:

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

To achieve this, I need to do some checks, so I came up with the following 'MAP':

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

I 'm having a hard time creating the pseudo- code, I know it's something that can be done recursively, but I'm stuck . The biggest problem is because of nested, I can have several levels of nested, not necessarily two.

In the last hours I created the following code:

'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});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's not an ES6 solution but it's relatively simple to understand:

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

Output:

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

Demo here.
Regex demo.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...