【问题标题】:What is the general solution to split strings inside strings in order to get a multidimensional array?为了获得多维数组,在字符串中拆分字符串的一般解决方案是什么?
【发布时间】:2018-08-02 00:07:34
【问题描述】:

如何实现一个拆分字符串的函数,可以递归地拆分字符串内的字符串?它应该是这样的:

返回一个0d数组(原始字符串):

var arr=mySplit('a',[]);
//arr='a'

返回一维数组:

var arr=mySplit('a|b',['|']);
//arr=['a','b']

返回一个二维数组:

var arr=mySplit('a,1|b,2',['|',',']);
//arr=[['a','1'],['b','2']]

返回一个 3D 数组:

var arr=mySplit('a:A,1:One|b:B,2:Two',['|',',',':']);
//arr=[[['a','A'],['1','One']],[['b','B'],['2','Two']]]

我尝试从 0d 到 2d 分别实现:

0D:

var split0d=function(str,sep){
    return str;
}
document.write(split0d('a',[]));

一维:

var split1d=function(str,sep){
    let result=[];
    result=str.split(sep[0]);
    return result;
}
document.write(split1d('a|b',['|']));

二维:

var split2d=function(str,sep){
    let result=[];
    
    let arr1=str.split(sep[0]);
    for(let i=0;i<arr1.length;i++){
        result.push(arr1[i].split(sep[1]));
    }

    return result;
}
document.write(split2d('a,1|b,2|c,3',['|',',']));

但我仍然不知道如何实现这个问题的一般解决方案,因为 0D 到 2D 的代码对我来说看起来非常不同。如何实现递归拆分字符串内部字符串的一般解决方案?

【问题讨论】:

  • 发布上述每种情况的预期结果数组

标签: javascript string algorithm multidimensional-array


【解决方案1】:

递归是正确的想法。

但我仍然不知道如何实现这个问题的一般解决方案,因为 0D 到 2D 的代码对我来说看起来非常不同。

好的,那我们稍微重写一下:

function split1d(str1, sep) {
    let result1 = [];
    let arr1 = str1.split(sep[0]);
    for (let i=0;i<arr1.length;i++) {
        let str2 = arr[i];
        result1.push(str2);
    }
    return result1;
}

function split2d(str2, sep) {
    let result2 = [];
    let arr2 = str2.split(sep[0]);
    for (let j=0; j<arr2.length; j++) {
        let str1 = arr[j];
        let result1 = [];
        let arr1 = str1.split(sep[1]);
        for (let i=0; i<arr1.length; i++) {
            let str0 = arr1[i];
            result1.push(str0);
        }
        result2.push(result1);
    }
    return result2;
}

现在有什么相似之处?

当然,当使用Array map 方法时,整个事情变得更容易发现:

function split0d(str0, sep) {
    return str0;
}
function split1d(str1, sep) {
    return str1.split(sep[0]).map(str0 => str0);
}
function split2d(str2, sep) {
    return str2.split(sep[0]).map(str1 => str1.split(sep[1]).map(str0 => str0));
}

你可以看到它变成了什么

function split0d(str0, sep) {
    return str0;
}
function split1d(str1, sep) {
    return str1.split(sep[0]).map(str0 => split0d(str0, sep.slice(1)));
}
function split2d(str2, sep) {
    return str2.split(sep[0]).map(str1 => split1d(str0, sep.slice(1)));
}

现在把它变成一个检查sep.length 的通用递归函数应该很简单了。

【讨论】:

  • 非常漂亮的图案展示
【解决方案2】:

您可以使用map 进行循环,然后让回调进行递归调用。 slice 将确保使用的分隔符不会传递给递归调用。当没有更多的分隔符时,第二个参数将是一个空数组,在这种情况下,字符串应该按原样返回:

function mySplit(s, sep) {
    return sep.length ? s.split(sep[0]).map( s => mySplit(s, sep.slice(1)) ) : s;
}

// Sample call
const result = mySplit('a:A,1:One|b:B,2:Two',['|',',',':']);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我不得不承认,我花了很多时间思考线性迭代过程,以至于我不记得如何设计递归过程。完美的编码。 A+
【解决方案3】:

映射和递归会起作用吗?

var mySplit = (str,sep)=>{
  const recur = (all,sep)=>
    (sep.length===0)
      ? all
      : all.split(sep[0]).map(item=>recur(item,sep.slice(1)));
  return recur(str,sep);
}
console.log(
  JSON.stringify(
    mySplit('a:A,1:One|b:B,2:Two',['|',',',':']),
    undefined,
    2
  )
);

【讨论】:

    【解决方案4】:

    你可以简单地做如下;

    var splitND = (ss,[d,...ds]) => d ? ss.split(d)
                                          .map(s => splitND(s,ds))
                                      : ss,
        result  = splitND('a:A,1:One|b:B,2:Two',['|',',',':']);
    console.log(JSON.stringify(result));

    【讨论】:

      猜你喜欢
      • 2020-01-30
      • 1970-01-01
      • 2020-08-05
      • 2022-10-04
      • 1970-01-01
      • 1970-01-01
      • 2019-01-17
      • 1970-01-01
      • 2022-01-02
      相关资源
      最近更新 更多