一番上のフォルダからの相対パスを取得するには?


ダッハウ  2014-03-23 00:32:55  No: 46151

C:\AAA\aaa.txt
C:\AAA\bbb.txt
C:\AAA\BBB\ccc.txt

とかのリストがあり、そのアドレスの順番は不明。
な場合、C:\AAAからの相対パスに変換させたいんですが、どうすればいいんでしょうか?
圧縮で使いたいんですが。

.\aaa.txt
.\bbb.txt
.\BBB\ccc.txt

としたい。

一列目にC:\AAA\BBB\ccc.txtが入ることも予想されるので、単に一番最初のパスの親フォルダとは行きません。

一回ループして、区切り文字を数えて、一番小さいものを取得し、そこから相対パスを比較する・・・、って手段ですかね?

相対パスはExtractRelativePath(Path1, Path2)で求めるとして、Path1はどう取得するのがスマートなのかなー?と。

よろしくおねがいします。


DEKO  2014-03-23 05:01:56  No: 46152

ちょっと付け加えるならこんな感じでしょうか?

1.全リストを検索し、パスの深さが一番浅いものを確定する。-> 基準パス
2.全リストから基準パスを検索する。
3.すべてのアイテムに一致しないなら基準パスを一段切り上げる。
4.すべてのアイテムに一致するか、パスルートに到達するまで繰り返す。


tor  2014-03-23 08:44:16  No: 46153

自分がやるなら、各項目を区切り文字で分割してツリーに登録していきますかね。

C: -+- AAA -+-- aaa.txt
            +-- bbb.txt
            +-- BBB
                 +--ccc.txt

ツリーができあがったらルートから順に、子が一つしかないノードを取り除いていきます。
子を二つ以上持つノード(上の例だとAAA)に行き当たったらそこまでが基準パスになります。
後はそのサブツリーをリストに変換しても良し、元のリストから基準パスに相当する部分を取り除いても良し。


ダッハウ  2014-03-23 19:55:18  No: 46154

DEKOさん、torさん、コメントありがとうございます。

ふと、出先なので、ExtractRelativePath(Path1, Path2)を触っていないので申し訳ないのですが、パスの深さが一番浅いものを確定しさえば、あとはExtractRelativePathがなんとかしれくれるのでは?

あれ?違うかな?^^;
そうなら、パスの深さが一番浅いものを、どうやって探すのがスマートなのかなー?と。
ライブラリとして使いまわす予定なので、できるだけ齟齬がないように作りたい。

DEKOさんの、
2.全リストから基準パスを検索する。
は、明らかにパスの先が違うものの対処ですかね?

C:\AAA\AAA\aaa.txt
C:\AAA\AAA\BBB\ccc.txt
F:\FFF\ccc.txt
↑とか、紛れ込む可能性も、確かにないとは言えないので、エラーチェックとして、基準パスを検索する必要は、確かにありますね。
フォルダをドロップして、サブフォルダのファイルリストを取得するイメージだったので、完全に想定外でした。
確かに、このエラー処理は必要ですね。


tor  2014-03-24 19:49:07  No: 46155

まあ基準パスを探す処理自体はアュで済むのではないかと思います。

まずパスリストの先頭要素から最後のファイル名を取り除いたものを暫定基準パスとします。
ついでに区切り文字でモモして要素に分割しておきます。
ヲサヲサヲサヲサァテコワチチチワョァヲサ→ヲサ暫定基準パスヲサスヲサロヲサァテコァャヲサァチチチァヲサン

この暫定基準パスをリストのイ番目以降のパス(を分割したもの)と順番に比較し、最長一致をとって更新していきます。

ヲサヲサヲサヲサリストのイ番目ヲサスヲサロヲサァテコァャヲサァチチチァャヲサァョァヲサン
ヲサヲサヲサヲサ暫定基準パスヲサヲサスヲサロヲサァテコァャヲサァチチチァヲサン
ヲサヲサヲサヲサュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュ
ヲサヲサヲサヲサ一致する要素ヲサヲサスヲサロヲサァテコァャヲサァチチチァヲサンヲサ←新しい暫定基準パス

ヲサヲサヲサヲサリストのウ番目ヲサスヲサロヲサァテコァャヲサァチチチァャヲサァツツツァャヲサァョァヲサン
ヲサヲサヲサヲサ暫定基準パスヲサヲサスヲサロヲサァテコァャヲサァチチチァヲサン
ヲサヲサヲサヲサュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュ
ヲサヲサヲサヲサ一致する要素ヲサヲサスヲサロヲサァテコァャヲサァチチチァヲサンヲサ←新しい暫定基準パス

ヲサヲサヲサヲサ……

この例だと最後までずっとヲサロヲサァテコァャヲサァチチチァヲサンヲサのまま変わらないので面白みがないですが、例えば途中でヲサァテコワトトトワナナナワョァヲサが出てきたら

ヲサヲサヲサヲサリストの番目ヲサスヲサロヲサァテコァャヲサァトトトァャヲサァナナナァャヲサァョァヲサン
ヲサヲサヲサヲサ暫定基準パスヲサヲサスヲサロヲサァテコァャヲサァチチチァヲサン
ヲサヲサヲサヲサュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュュ
ヲサヲサヲサヲサ一致する要素ヲサヲサスヲサロヲサァテコァヲサンヲサ←新しい暫定基準パス

このように更新されます。
仮にヲサァニコワワワョァヲサとか出てきたら暫定基準パスが空になるので、その場合はそこで探索を打ち切ります。
こうしてリストの最後まで行くと全部に共通する最小のパスが得られるので、
もう一回ループしてナメミで置き換えていけばよさそうですね。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーウッイエィ月ゥ アアコーウコオク  書込者ノト:ロ 」 ァ」ハノ

 ン

さらに考えてみると、区切り文字で分割とか小難しいことをしなくても
単純に文字列で比較して、最長一致を切り出していけば十分ですね。
最後に出た答えがヲサァテコワチチチワツツツワァヲサみたいにパス区切りで終わっていなかったら、そこで余分なァワァ以降を削ればいいです。
スススススススススススススススススススススススススススススススススススススススス
ニコ 改、ブノゾン
トコ イーアエッーウッイエィ月ゥ イーコーイコオア  書込者ノト:ロ 「「  ン

まず、適当につけたダッハウでしたが、強制収容所の名前でした。
不快な思いをされた方には、お詫びを。
すいませんでした。

でだ。
方法としては、ツリーに読み込ませるのが、一番いい気もしてきましたが、ツリー構造は、まだ良くわからないので、今回はシンプルに。

私案の区切り文字を数えて、一番小さいものを探す。
ただし、予想外のフォルダのエラー処理にもう一工夫。

さんの、暫定パス方式と、最長一致方式。
最長一致方式は、テですかね?テはあまり早い印象がないのですが、教えてもらった方法を、考慮に入れて、色々と実験してみたいと思います。

みなさんのご意見、とてもためになりました。
スススススススススススススススススススススススススススススススススススススススス
ニコ 改、ブノゾン
トコ イーアエッーウッイエィ月ゥ イーコーウコエエ  書込者ノト:ロ 「「  ン
モコ 

解決で。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加