質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

マージ

複数のデータベースやファイル、プログラムなどを決まった手順や規則に従って一つに結合すること。

Q&A

解決済

1回答

962閲覧

[Ruby(Rails)] Hashの共通キーの値を上書きせずにマージしたい

Matzka

総合スコア7

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

マージ

複数のデータベースやファイル、プログラムなどを決まった手順や規則に従って一つに結合すること。

0グッド

0クリップ

投稿2020/05/03 16:17

やりたいことの概要

railsにおいて、zipフォルダをアップロードされた際、そのディレクトリの構造をjson形式で以下の様に表現したい。

{ name: "test" isfile: false children: [ { name: "aaa.txt" isfile: true }, { name: "test1" isfile: false children: [ { name: "bbb.txt" isfile: true }, { name: "test2" isfile: false children: [ { name: "ccc.txt" isfile: true } ] }, { name: "test3" isfile: false children: [ { name: "ddd.txt" isfile: false } ] } ] } ] }

※なんとなくファイル構造を表現できていれば⇑と全く一緒じゃなくても全然問題ないです。

詳細及び現状

test ├── aaa.txt └── test1 ├── bbb.txt ├── test2 │   └── ccc.txt └── test3 └── ddd.txt

現状として、これをzip化したファイルをrails側で@filesという変数で受け取っていて、

@files = [ "test/aaa.txt", "test/test1/bbb.txt", "test/test1/test2/ccc.txt", "test/test1/test3/ddd.txt" ]

となっています。この情報からjbuilderで今の所@filesの各パスを下記のように表現できました
(配列に@filesの各パスをツリーで表現したhashが入っている状態)
イメージ説明

ただ、ここからどうやって最初の目標のjsonのように結合できるかがわからない状況です。
deep_mergeを使っても上書きされてしまい、上書きされないでchildrenのキー以下だけをマージできる方法を解答していただきたく投稿した次第です。

まとめ

結論としてやりたいことは、

  • 最後の画像のjsonを、最初の"やりたいことの概要"のjsonにどうやったら変形できるかが知りたい
  • あるいは@filesの情報から直で最初のjsonのようなファイル構造を表現する方法でも、なんかのgemを使ってzipfileのデータからファイル構造を取得する方法でも構わない

といった感じです。
よろしくお願いしますmm

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

jsonて文字データですから、これを編集するのはやめた方がよいと思います。
今までの成果を元にすすめるなら、そのjsonをJSN.loadして Hash, Arrayの構造に変換してからいじるのが良いでしょう。

ただ、ちょっとややこしそう。
私ですと、jsonの構造にあったデータ構造をまず作ります

["test", ["aaa.txt", ["test1", [ ["test2",[ "ccc.txt"]], ["test3",[ "ddd.txt"]] ] ] ] とか {"test" => {"aaa.txt", "test1" => { "test2" => "ccc.txt", "test3" => "ddd.txt" } } } とか

これからなら望みのjson組み立てられそうですか?

追記
dir配下のfileをまとめて階層ごと。
"basename" は適宜
Dir.glob(dir+"/**/*{csv,xlsx}") の拡張子も適宜

def compress_dir dir temp_file = Tempfile.new("basename") files = Dir.glob(dir+"/**/*{csv,xlsx}") Zip::File.open(temp_file.path, Zip::File::CREATE) do |zipfile| files.each do |file| filename = file.sub(/#{dir}//,"") if Rails.env == "development" zipfile.add(filename, file) else zipfile.add(filename.encode("Shift_JIS"), file) end end end temp_file.path end

投稿2020/05/04 01:01

編集2020/05/04 09:50
winterboum

総合スコア23329

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Matzka

2020/05/04 05:22 編集

回答ありがとうございます! たしかにこのような処理をjbuilderで記述するのは筋違いだと思いました…w ただ配列のまま構造を再現しようとして見たのですが、 ``` files = [ "test/aaa.txt", "test/test1/bbb.txt", "test/test1/test2/ccc.txt", "test/test1/test3/ddd.txt" ] @files.map! { |file| file.split('/') } testlist = [[],[],[],[]] lenlist = @files.map { |path| path.size } maxlen = lenlist.max @files.each_with_index do |path,index| maxlen.times do |i| break if path[i]==nil if path[i+1]==nil testlist[i].push([path[i],index]) else testlist[i].push(path[i]) unless testlist[i].include?(path[i]) end end end p testlist => [["test"], [["aaa.txt", 0], "test1"], [["bbb.txt", 1], "test2", "test3"], [["ccc.txt", 2], ["ddd.txt", 3]]] ``` 入れ子を繰り返し文などでどのように追加していくかがわからず詰まってしまうのが現状です… フォルダのダウンロードやアップロードの機能を備えているrailsのアプリケーションは多くあると思いますが、それらはどのようにしてこの問題を解決しているのでしょうか…?
winterboum

2020/05/04 05:59

フォルダのダウンロードやアップロードの機能を備えているrailsのアプリケーション  はいくつか作りましたが、【ファイル構造を別途渡す」ということは考えたことが無いです。構造を保ったまま固めて送ってますので。
Matzka

2020/05/04 06:40 編集

その構造を保ったまま固めて送るというのはどうやればいいのですか!? それができればこんなめんどくさいことやってないですww 目的としてはアップロードされたフォルダをgithubみたいな感じでエクスプローラー的に表示したり、アップロードされたフォルダ構造のままダウンロードとかしたい感じなのです
Matzka

2020/05/04 11:51

追記の方感謝です! なるほど、そのような方式で少しやってみようと思います、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問