【问题标题】:fill gap between alphanumeric array elements填充字母数字数组元素之间的间隙
【发布时间】:2018-03-30 00:19:13
【问题描述】:

我正在为一个简单的模式而苦苦挣扎:

['A1', 'A2', 'A5', 'E1', 'E4', 'E6']

我想填补每个字母数字范围之间的数字空白(原位或另一个数组中)

模式是 1 个字母与大于 1 的整数连接(如果您喜欢任意数量的字母,请随意)

所以这个示例数组会产生以下结果:

['A1', 'A2', 'A3', 'A4', 'A5', 'E1', 'E2', 'E3', 'E4', 'E5', 'E6']

我正在寻找最直接/最有效的方式,ES6 也欢迎

【问题讨论】:

  • 你不能用一个新数组覆盖数组吗?
  • 这始终是 1 个字符和 1 个数字还是 CA32 也是如此?
  • 你说的“我在挣扎”是什么意思?你有什么可以向我们展示的尝试吗?
  • 它总是1个字符,但可以是任何数字> 1

标签: javascript arrays sorting ecmascript-6


【解决方案1】:

您可以循环原始数组,然后比较值是否连续。如果不是,您可以使用循环填充该差异。

例如:

var result = [];
var arr = ['A1', 'A2', 'A5', 'E1', 'E4', 'E6'];
arr.sort();

for (var i = 0; i < arr.length; i++) {
    var curr = arr[i];
    result.push(curr);
    if (arr[i + 1]) {
        var next = arr[i + 1];
        if (curr.charAt(1) < next.charAt(1)) {
            for (var y = parseInt(curr.charAt(1), 10) + 1 ; y < parseInt(next.charAt(1)); y++) {
                result.push(next.charAt(0) + y);
            }
        }

    }
}
console.log(result);

将导致:

[“A1”、“A2”、“A3”、“A4”、“A5”、“E1”、“E2”、“E3”、“E4”、“E5”、“E6”]

【讨论】:

    【解决方案2】:

    您可以使用reduce 方法来做到这一点。

    另外,通过传递regex 模式来使用replace 方法,以便从E1 中找出text,即Enumber,即1

    这个想法是从给定数组中查找两个元素consecutive,并使用for 循环添加缺少的元素。

    let array=['A1', 'A2', 'A5', 'E1', 'E4', 'E6']
    array = array.reduce(function(arr,item,i){
      if(i>0){
        var [elemNr,elemStr]=[item.replace( /\D+/g, ''),item.replace(/[0-9]/g, '')];
        var [lastElemNr, lastElemStr]=[array[i-1].replace( /\D+/g, ''),array[i-1].replace(/[0-9]/g, '')];
        for(j=lastElemNr;j<=elemNr;j++) 
           if(arr.indexOf(elemStr+j)==-1)
              arr.push(elemStr+j);
      }
      return arr;
    },[]);
    console.log(array);

    【讨论】:

      【解决方案3】:

      您可以使用Array#reduce,在其中查看给定数组的两个元素并用while 循环填充缺失的部分,同时进行计数。

      var array = ['Z0', 'A1', 'A2', 'A5', 'B4','E1', 'E4', 'E6', 'G2'],
          result = [];
      
      array.reduce(function (a, b) {
          var aa = (a || b).match(/(\D+)(\d+)/).slice(1),
              bb = b.match(/(\D+)(\d+)/).slice(1);
      
          if (aa[0] === bb[0]) {
              while (++aa[1] < bb[1]) {
                  result.push(aa.join(''));
              }
          }
          result.push(b);
          return b;
      }, undefined);
      
      console.log(result);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        【解决方案4】:

        如果数字有最大值,您还可以考虑 Hash-Map/Table(例如 Dictionary)。

        var sourceYours = ['A1', 'A2', 'A5', 'E1', 'E4', 'E6']
        
        1. 获取 Alpha 部分

        2. 查找该 Alpha 的 Max-Numeric-Part

        3. 获取“A5”的字典条目 -> 返回['A1', 'A2', 'A3', 'A4', 'A5']

        4. 连接所有字典返回

        应该是最快的方法。消耗更多内存。必须先创建字典。 预计有限的最大编号部分。

        【讨论】:

          【解决方案5】:

          试试这个:

          function fill(theArray){
            theArray = theArray.sort().reverse();
            var newList = [];
            for (let el of theArray) {
              let newListLenght = newList.length;
              if (!newListLenght || newList[newListLenght-1].charAt(0) !== el.charAt(0)){
                let maxNumber = parseInt(el.charAt(1));
                for (let number = 1; number < maxNumber; number ++){
                  newList.push(el.charAt(0) + number);
                }
              }
            };
            return newList.sort();
          }

          即使对无序元素也有效

          【讨论】:

            【解决方案6】:

            您可以遍历您的数组一次以收集以下信息:

            • 你有哪些 alpha 部分
            • 每个 alpha 部分的左右(最小和最大)边界是什么

            在您的示例中,在第一次迭代后,我们将知道有两个 alpha:

            • A,从 1 到 5
            • E,从 1 到 6

            现在,您可以生成答案了。

            演示:

            var sourceYours = ['A1', 'A2', 'A5', 'E1', 'E4', 'E6']
            var sourceComplex = ['A1', 'A2', 'A5', 'E1', 'E4', 'E6', 'D2', 'D4', 'E7'];
            
            console.log(fillGaps(sourceYours));
            console.log(fillGaps(sourceComplex));
            
            function fillGaps(arr) {
              var alphas = {};
              
              arr.forEach(function(x) {
                var alpha = x.replace(/\d/, ""), 
                    numeric = +x.replace(/\D/, "");
                
                if (!alphas[alpha]) {
                  alphas[alpha] = {
                    min: numeric,
                    max: numeric
                  };
                } else {
                  alphas[alpha].min = Math.min(alphas[alpha].min, numeric);
                  alphas[alpha].max = Math.max(alphas[alpha].max, numeric);
                }    
              });
              
              var result = [];
              for (var alpha in alphas)
              {
                for (var num = alphas[alpha].min; num <= alphas[alpha].max; num++)
                {
                  result.push(alpha + num);
                }
              }
              
              return result;
            }

            这个解决方案有很多地方需要改进或缩短,它取决于您的 ECMASript 版本限制,但它显示了这个想法。
            我还假设始终保证这种格式:{alpha part}{numeric part}。如果不是,那么它也需要改进。

            【讨论】:

            • 这当然提供了更冗长的解决方案之一,但它也是最容易阅读的。 +1
            猜你喜欢
            • 1970-01-01
            • 2017-05-22
            • 1970-01-01
            • 2019-12-05
            • 1970-01-01
            • 2010-11-07
            • 2015-02-28
            • 1970-01-01
            • 2022-08-18
            相关资源
            最近更新 更多