从路径字符串 - Javascript 获取所有父路径

Get all parent paths from Path String - Javascript

本文关键字:路径 获取 Javascript 字符串      更新时间:2023-10-29

我需要一些关于字符串操作的建议。这是一个可能的字符串:

"/branches/projects/MyTool/MyTool/someOtherFolderOrFile"

我需要的是一个包含以下内容的数组:

 ['/branches', '/branches/projects','/branches/projects/MyTool','/branches/projects/MyTool/MyTool']

因此,为了澄清此数组应包含的内容:最后一个文件或文件夹的所有父路径。数组中排除最后一个文件或文件夹。

我知道我可以在"/"拆分字符串,然后可以迭代数组,连接字符串并从数组中删除最后一个条目。我将递归调用此方法,直到数组中没有元素为止。然后,串联的字符串将在每次迭代时保存到一个新数组中,该数组将在最后保存所需的结果......

但是,我

问我如何做到非常干净和简单,我相信你们中的某个人可以想出一个极好的解决方案:)

编辑这是我刚才提出的当前解决方案:

var string = "/branches/projects/MyTool/MyTool/anotherFolderOrFile";
var helperArr = string.split("/");
var endArray = [];
getParentArray();
console.log(endArray);
function getParentArray() {
    if(helperArr.length == 1) {
        return;
    }
    else {
        var helperString = "";
        for(var i = 0;i<helperArr.length;i++) {
            helperString = helperString+helperArr[i];
            if(i!= helperArr.length -1) {
                helperString = helperString+"/";
            }
        }
        endArray.push(helperString);
        helperArr.length = helperArr.length-1;
        getParentArray();
    }
}

这是一个紧凑的解决方案,但它可能不像@somethinghere那样清晰:

var path= '/branches/projects/MyTool/MyTool/someOtherFolderOrFile'.split('/'),
    paths= [];
path.shift();
while(path.length > 1) {
  paths.push((paths[paths.length-1] || '') + '/' + path.shift());
}
alert(paths.join(''r'));

更新

感谢您的评论。 这是一个更紧凑的版本,不需要拆分或移动:

var path= '/branches/projects/MyTool/MyTool/someOtherFolderOrFile',
    paths= [],
    i = 1;
while(i = path.indexOf('/',i)+1) {
  paths.push(path.substr(0,i));
}
alert(paths.join(''r'));

更新 #2

只是为了咯咯笑,第三种解决方案,应该比我的其他解决方案更清晰,但仍然比@somethinghere的慢一点:

var path= '/branches/projects/MyTool/MyTool/someOtherFolderOrFile',
    paths= [],
    i;
for(var i = 1 ; i < path.length ; i++) {
  if(path[i]==='/') paths.push(path.substr(0,i));
}
 
alert(paths.join(''r'));

这将解决问题:

/* First split the path at any folders separator ('/')*/
var splitPath = "/branches/projects/MyTool/MyTool/someOtherFolderOrFile".split("/");
/* Initialise a final array to save the paths. Store the first one in there! */
var endPaths = [splitPath[0] + "/"];
/* Check if there are multiple paths available */
if(splitPath.length >= 2){
    /* Run through each and append it to the last saved one, then add it to the results.*/
    for(var i = 1; i <= splitPath.length-1; i++){
        endPaths.push(endPaths[i-1] + splitPath[i] + "/")
    }
}

这将包括/作为路径,从技术上讲,这是路径。如果您不希望这样,可以在初始化时使用此行来排除任何简单的路径,如下所示:

var endPaths = splitPath[0] != "" ? [splitPath[0] + "/"] : [];

但是,如果您执行上述操作,请注意您的循环会抛出错误,因为当您的循环开始时endPaths[i-1] undefined,您必须在 for 循环中执行检查:

/* You need to do -2 as you start at 1, but you only want to add paths from 2 upwards.*/
var prevPath = typeof endPaths[i-2] !== "undefined" ? endPaths[i-2] : "";
endPaths.push(prevPath + splitPath[i] + "/")

而且,为了获得更多种类,一个递归的、基于 RegEx 的解决方案:

function iterateMatch(testString, currPattern, results) {
    var regexTestPattern = new RegExp("^" + currPattern + "'/[^'/]+");
    results.push(testString.match(regexTestPattern)[0]);
    if (results[results.length - 1] !== testString) {
        iterateMatch(testString, results[results.length - 1], results)
    }
}

该函数接受:

  1. 测试字符串,
  2. 在比赛中"忽略"的模式
  3. 要将结果转换为的数组

"忽略"模式将作为空白字符串开始,但在每次迭代期间,将包含以前匹配的目录级别。 此字符串用作匹配模式的开头,然后匹配模式将 RegExp 模式添加到末尾,其中包含用于匹配正斜杠和一个或多个非斜杠字符的 RegExp 模式。

匹配项在结果数组中捕获,如果它不等于测试字符串,则作为下一个"忽略"模式(以及原始测试字符串和结果数组(再次传递到 iterateMatch 函数中,以便匹配开始向下查看下一级。

当像这样调用时,使用您的测试字符串:

var sTestString = "/branches/projects/MyTool/MyTool/someOtherFolderOrFile";
var sCurrPattern = "";
var aResults = [];
iterateMatch(sTestString, sCurrPattern, aResults);
console.log(aResults);

。结果是:

 ["/branches",
  "/branches/projects",
  "/branches/projects/MyTool",
  "/branches/projects/MyTool/MyTool",
  "/branches/projects/MyTool/MyTool/someOtherFolderOrFile"]

> 这个reduce解决了我的用例(没有前面的/(:

const string = "a/b/c/d";
const stringSplits = string.split('/');
const parentArray = stringSplits.reduce((acc, val, i) => {
  if (i === 0) return [val]
  acc.push( acc[i-1] + '/' + val )
  return acc
}, []);
// returns ["a", "a/b", "a/b/c", "a/b/c/d"] 

或者这个单行,如果你绝对是疯子:

const parentArray = "a/b/c/d".split('/').reduce((acc, val, i) => i === 0 ? [val] : [].concat(acc, acc[i-1] + '/' + val ), []);

一点也不短,一点也不优雅...有点不同的方法...

function split_string_to_path( str ) {
  if (typeof str == "undefined")
    return false; // return, if no string
  split_path = str.split("/"); // splitted string
  result_arr = []; // result paths into this variable
  tmp_arr = []; // temporary, for join
  for( i = 0; i < split_path.length; i++ ) { // loop through all elements
    tmp_arr.push( split_path[i] ); // push element
    result_path = tmp_arr.join( "/" );
    if ( result_path.length > 0 )
      result_arr.push( tmp_arr.join( "/" ) ); // join tmp arr to path and add it to result_arr
  }
  return result_arr;
}
split_result = split_string_to_path( "/branches/projects/MyTool/MyTool/someOtherFolderOrFile" ); // run function
console.log( split_result ); // output on console
这是我

的看法。使用一点jQuery来帮助我们做一个很好的简洁函数(即使它有点低效(。

    function getParentArray(path) {
        // split up on the forward slashes
        var splitPath = path.split('/');
        // Don't need the last part of the path
        splitPath.pop();
        // put an ever growing slice of the original path into a new array
        return $.map(splitPath, function(value, i) {
            return '/' + splitPath.slice(1, i + 1).join('/');
        }).splice(1);
    }
    var samplePath = '/branches/projects/MyTool/MyTool/someOtherFolderOrFile';
    var parentArray = getParentArray(samplePath);
    alert(parentArray.join(''n'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

尝试

var str = "/branches/projects/MyTool/MyTool/someOtherFolderOrFile"
, d = "/"
, arr = str.split(d).filter(Boolean)
, res = arr.map(function(val, i) {
            return i < 1 ? d + val : d + arr.slice(0, i).join(d) + d + arr[i] 
  }).slice(0, arr.length - 1);

    var str = "/branches/projects/MyTool/MyTool/someOtherFolderOrFile"
    , d = "/"
    , arr = str.split(d).filter(Boolean)
    , res = arr.map(function(val, i) {
              return i < 1 ? d + val : d + arr.slice(0, i).join(d) + d + arr[i] 
      }).slice(0, arr.length - 1); 
document.querySelectorAll("pre")[0].innerText = JSON.stringify(res, null, 4)
<pre></pre>