NodeJS循环遍历字符串并获得准确的输出

时间:2018-04-04 02:03:17

标签: javascript node.js string

在NodeJS中,我有一个像这样的字符串

"Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?"

在字符串中,您可以看到有多个Package,Qty和Price。现在我想为每个Qty和Package发送电子邮件。因此,如果您看到第二个包它有数量3.那么在那种情况下,它将发送3封电子邮件与包和价格。所以基本上它会为每个数量发送相应的套餐和价格的电子邮件。

所以现在我的代码就像这样

var string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
var packArr = string.split('?');
var PackageName;
var PackagePrice;
for (var i = 0; i < packArr.length; i++) {
  if( packArr[i].length > 0 ) {
    let packageQty = packArr[i].split('&');
    for (var j = 0; j < packageQty.length; j++) {
      if( packageQty[j].match(/Package=/i) ) {
        PackageName = packageQty[j].replace(/Package=/g,'');
          console.log(PackageName);
      }

      if( packageQty[j].match(/Price=/i) ) {
        PackagePrice = packageQty[j].replace(/Price=/g,'');
          console.log(PackagePrice);
      }

      if (packageQty[j].match(/Qty=/i)) {
        var ret = packageQty[j].replace(/Qty=/g,'');
        var Pck = Number(ret);
        for (var k = 1; k <= Pck; k++) {
          console.log(k);
          console.log('Package Name ' + PackageName);
          console.log('Package Price ' + PackagePrice);
          //send email with Package Name, Package Price 
          if( k == Pck ) {
            break;
          }
        }
      }
    }
  }
}

以上代码实际上无法正常工作。没有为每个循环正确获得Package和Price。那么有人能告诉我如何以一种简单的方式做到这一点吗?任何帮助和建议都会非常明显。

5 个答案:

答案 0 :(得分:2)

使用querystring

,这是一种更清洁的方法
const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";

const qs = require('querystring');

// We split the string into multiple valid query strings.
// We strip the empty item due to the '?' at the end using .filter(Boolean)
const items = string.split('?').filter(Boolean);

// We loop through each group
for(const query of items) {
    // Parse the query string of each group
    const { Package, Qty, Price } = qs.parse(query);

    for(let i = 0; i < Number(Qty); i++) {
        // We send the email here <Qty> times.
        console.log('Package Name ' + Package);
        console.log('Package Price ' + Price);
    }
}

答案 1 :(得分:0)

我不知道您对图书馆的看法,但Ramda(免责声明:我是其中一位作者)非常适合数据转换。这引起了一些直接的数据转换。

我可能会用它来编写一个转换函数,将初始数据更改为:

[
  {Package: "Package",       Price: 123, Qty: 1}, 
  {Package: "Package Two",   Price: 702, Qty: 3},
  {Package: "Package Three", Price: 199, Qty: 1}, 
  {Package: "Package One",   Price: 852, Qty: 4}
]

这种新格式应该易于使用。

以下是执行此操作的实现:

&#13;
&#13;
const {pipe, split, filter, map, fromPairs, evolve} = R;

const str = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";

const convertToObjects = pipe(
  split('?'),
  filter(Boolean),
  map(split('&')),
  map(map(split('='))),
  map(fromPairs),
  map(evolve({Price: Number, Qty: Number}))
);

console.log(convertToObjects(str))
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
&#13;
&#13;
&#13;

  • mapsplitfilter应该是显而易见的。
  • fromPairs[['a', 1], ['b', 2]]变为{a: 1, b: 2}
  • evolve将属性名称映射到转换函数,并通过将这些函数应用于相关属性来转换对象,从而保持所有其他属性不变。在这里,我们使用JS Number函数将{Package: 'Foo', Qty: '2', Price: '456'}转换为{Package: 'Foo', Qty: 2, Price: 456}
  • pipe创建一个函数管道,其中一个函数的输出成为下一个函数的输入。提供给结果函数的值将发送到第一个,并返回最后一个的结果。

答案 2 :(得分:0)

使用普通javascript在没有外部依赖的情况下扩展@ Marcos-casagrande示例

const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";

// We split the string into multiple valid query strings.
// We strip the empty item due to the '?' at the end using .filter(Boolean)
const items = string.split('?').filter(Boolean);

// We loop through each group
items.map(query => {
  // Parse the query string of each group
  const {
    Package,
    Qty,
    Price
  } = query.split('&').reduce((acc, cur) => {
    let arr = cur.split('=');
    return {
      ...acc,
      [arr[0]]: arr[1]
    };
  }, {});

  for (let i = 0; i < Number(Qty); i++) {
    // We send the email here <Qty> times.
    console.log('Package Name ' + Package);
    console.log('Package Price ' + Price);
  }
})

答案 3 :(得分:0)

另一种仅使用正则表达式和一些数组方法的方法,不需要嵌套循环

var input = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?"

var results = input
  .split('?')
  .map(s => /^Package=(.*?)&Qty=(.*?)&Price=(.*?)$/.exec(s))
  .filter(s => s)
  .map(s => ({ 
      package: s[1], 
      qty: parseFloat(s[2]), 
      price: parseFloat(s[3]) 
  }))

console.log(JSON.stringify(results, null, 4))

答案 4 :(得分:0)

这是一个纯粹的JS替代方案,请看一下。

function extract(name, string) {
  name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
  var regexS = "[\\?&]" + name + "=([^&#]*)";
  var regex = new RegExp(regexS);
  var results = regex.exec(string);
  return results == null ? null : results[1];
}

function parse(string) {
  items = string.split('?');
  results = [];
  for (var i in items) {
    if (items[i].length == 0) continue;
    var item = '?' + items[i];
    results.push({
      package: extract("Package", item),
      qty: extract("Qty", item),
      price: extract("Price", item)
    })
  }
  return results;
}
str = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
document.getElementById('output').innerText = JSON.stringify(parse(str));
<div id='output'></div>