challenge 擬似lsの実装

スラッシュで区切られた文字列の配列(以下パスリスト)がある。
このパスリストにたいして擬似的なlsを行いたい。
lsはパスリストと表示対象ディレクトリのパスを入力する。

例としては以下のようになる。
pathList = ["aaa/bbb","aaa/ccc","aaa/ddd/eee","bbb/ddd/eee"]

ls(pathList,"aaa/")
>["bbb","ccc","ddd/"]

ls(pathList,"aaa/ddd/")
>["eee"]

なおパスリストが大きくなったとき、速度がなるべく低下しないように実装するのが望ましい。
文字列は任意の文字コードであると仮定してかまわない。

Posted feedbacks - C#

縮めた感じで。

1
2
3
4
5
6
7
8
9
static void ls(string[] pathList, string path)
{
    int i;
    Console.WriteLine(
        pathList.Where( x => x.IndexOf(path) != -1 )
                .Select( x => x.Substring( path.Length, (i = x.IndexOf( "/", path.Length )) == -1 ? x.Length-path.Length : i-path.Length+1 ) )
                .Aggregate(new StringBuilder(), (sb, s) => sb.Append(s).Append(" "))
    );
}

C#2.0 で。new List<string> のあたりがもうちょっと何とかなりそうな気がするけど……。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
static class Program {
    static void Main() {
        string[] pathList = {"aaa/bbb", "aaa/ccc", "aaa/ddd/eee", "bbb/ddd/eee", "bbb/ddd/fff"};
        Console.WriteLine("[{0}]", string.Join(", ", Ls(pathList, "aaa/")));
        Console.WriteLine("[{0}]", string.Join(", ", Ls(pathList, "aaa/ddd/")));
        Console.WriteLine("[{0}]", string.Join(", ", Ls(pathList, "bbb/")));
        Console.WriteLine("[{0}]", string.Join(", ", Ls(pathList, "bbb/ddd/")));
    }
    static string[] Ls(string[] paths, string pattern) {
        SortedList<string, string> list = new SortedList<string, string>();
        Array.ForEach(paths, delegate(string x) {
            if (x.StartsWith(pattern)) {
                x = x.Substring(pattern.Length);
                int i = x.IndexOf('/');
                list[i < 0 ? x : x.Substring(0, i + 1)] = null;
            }
        });
        return new List<string>(list.Keys).ToArray();
    }
}

C#3.0で拡張メソッドを使ってみました.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Linq;
using System.Collections.Generic;

static class Program {
    static string RemoveAfter(this string s, char ch) {
        int index = s.IndexOf(ch);
        return (0 <= index && index < s.Length - 1) ? s.Remove(index + 1) : s;
    }
    static void ls(IEnumerable<string> pathList, string path) {
        if (!path.EndsWith("/")) path += '/';

        var x = from y in pathList where y.StartsWith(path)
                select '"' + y.Substring(path.Length).RemoveAfter('/') + '"';

        Console.WriteLine("[{0}]", string.Join(", ", x.Distinct().ToArray()));
    }
    static void Main(string[] args) {
        string[] pathList = { "aaa/bbb", "aaa/ccc", "aaa/ddd/eee", "bbb/ddd/eee" };

        ls(pathList, "aaa/");
        ls(pathList, "aaa/ddd/");
    }
}

とりあえずでLINQを使ってみました。 LINQを使う前提で作ったのが原因では無いと思いますが、可読性の低いコードだなぁ・・・

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class LsClone
{
    static void Main(string[] args)
    {
        string[] pathList = {"aaa/bbb","aaa/ccc","aaa/ddd/eee","bbb/ddd/eee"};
        Console.WriteLine( ls(pathList, "aaa/") );
        Console.WriteLine(ls(pathList, "aaa/ddd/"));
        Console.WriteLine(ls(pathList, "bbb/ddd/"));
    }

    public static string ls(string[] pathList, string pattern)
    {
        string str = "[";
        var list = from path in pathList where  path.Length> pattern.Length && path.Substring(0, pattern.Length)==pattern
                   select path.Remove(0, pattern.Length).IndexOf('/') == -1 ? path.Remove(0, pattern.Length) : path.Split( new char[]{'/'})[1]+"/";
        foreach (string p in list) str += "\"" + p + "\",";
        return str.Substring(0,str.Length-1) + "]";
    }
}

Index

Feed

Other

Link

Pathtraq

loading...