イントロ
dataコマンドなどでデータを取得するなどするとき、
なんとなくで記述して結局できず親階層から丸ごと取得して表示された中から目的のデータを探して……、みたいなことはないだろうか。
そんなテキトー記述を卒業して正確に書けるようになってつよつよダーになろう!
本編
初級
まずは小手調べ。
{A:1}
上のようなストレージが合ったとき、Aのデータである1を取得するにはどうすればいいだろうか?
data get storage _:_ A
# 結果: 1
もちろんこうだね。
{B:1b,C:"しぃ"}
数値の場合はもちろん、上のような真偽値やテキストの場合でも同様に
data get storage _:_ B
# 結果: 1b
data get storage _:_ C
# 結果: "しぃ"
のようになる。
中級
{D:{E:e}}
ちょっとレベルアップだよ。
こんな感じで階層構造になったらどうすればいい?
ひとまず同じ用にDとだけ指定してみよう。
data get storage _:_ D
# 結果: {E:e}
この場合は結果が{E:e}と、この階層すべてが取得されるよ。
ではEのデータであるeを取得するにはどうすれば良いかな?
階層に入り込んでいくときは. (ドット)を挟んで表すよ。
つまり、
data get storage _:_ D.E
# 結果: e
こうなる。
{D:{F:0b,G:"じぃ"}}
では上記の場合に、Fの中の0b、Gの中の"じぃ"を取得してみよう。
data get storage _:_ D.F
# 結果: 0b
data get storage _:_ D.G
# 結果: "じぃ"
そうだね、初級の時と同じだ。
階層が変わったからといって指定の方法が変わるわけじゃないよ。
逆にここで単にDとして指定するとどうなるだろう?
data get storage _:_ D
# 結果: {F:0b,G:"じぃ"}
まあ当然と言えば当然だね。
Dの中身である{F:0b,G:"じぃ"}全体が取得されたよ。
上級
さて、階層移動の方法がわかったね。
これでキミはサイキョーだ。
さてさて。
{H:["h"]}
では"h"を取得してみようか。
「そんなの簡単だよ、こうやって───
data get storage _:_ H
# 結果: ["h"]
ほらこれで。」
となったキミは詰めが甘いネ。
["h"]ではリストごと取得してしまっているのがわかるかな?
"h"のテキストデータとして取得出来ていないんだよね。
たとえば["minecraft:grass_block"]となっていたとしてこのidがほしいとする。
このときに["minecraft:grass_block"]として取れてしまうと、取得したデータをそのままidとして使えないよね。
てことはやっぱり"minecraft:grass_block"として取得するほうが使いやすい。
じゃあどうしようか?
答えはこうだよ。
data get storage _:_ H[]
# 結果: "h"
このように[] (大括弧) を後ろにつけるとリストの中身に入ることができるよ。
ではこの場合はどうだろうか。
{H:["h","i"]}
さっきと違うところはリストに複数の要素があるところだね。
とりあえずH[]で取ってみようか。
data get storage _:_ H[]
-# 結果: この引数には単一のNBTを返すことが出来ます。
おっとエラーだね。
そう、data getでは複数の要素を一度に返すことは出来ないよ。
鋭いキミは気付くだろう。
「{F:0b,G:"じぃ"}って返されたあれはいいの???」
非常に良い質問です。
結論: いいんです
確かに{F:0b,G:"じぃ"}は単一でないように見える。
けどこれは["h"]と同じように、複数の要素(F:0b,G:"じぃ")が入った{}という単一の要素であるわけだ。
では今回はというと、もしエラーを出さずに取れていたとしたら"h","i"だね。
これは明確に複数の要素だと言える。
さてこれを取得するには単一の要素である必要があるね。
それをするにはこうだ。
data get storage _:_ H[1]
# 結果: "i"
[] (大括弧) の中に添字(そえじ)を入れることによって指定することができるよ。
添字というのはリストなどの要素の番号を示すもので、
今回であれば["h","i"]であるから
-
[0]:"h" -
[1]:"i"
となるよ。
0から始まることに気をつけよう。
次はこれだ。
{Items:
[{Slot:0b,Count:1b,id:"minecraft:iron_ingot"},
{Slot:22b,Count:1b,id:"minecraft:gold_ingot"}]}
打って変わって実用的なコンテナ系のデータ(Items)だよ。
じゃあこれの"minecraft:gold_ingot"を取得してみよう。
data get storage _:_ Items[1].id
# 結果: "minecraft:gold_ingot"
この用に、リストでも単一の要素でさえあれば . (ドット) での階層移動も問題なく行えるよ。
{Items:
[{Slot:0b,...},
{Slot:1b,...},
{Slot:2b,...},
...]}
ではこんな風にスロットがいっぱいあるうちのどれかから、
例えばSlot:17bにしようか。
からidを取得したい場合を考えよう。
言い換えると、任意のデータに該当する要素を指定する方法だね。
ストレージの構造が先程とほとんど同じなことを考えると、
Items[].idと形が似ていることが直感的に理解できるだろう。
とりあえずやってみるね。
data get storage _:_ Items[{Slot:17b}].id
# 結果: "minecraft:diamond"
お、ダイヤが入ってたみたいだね。
こんな風に
[] (大括弧) の中に {} (中括弧) を入れてそこに任意のデータを入れることで、それに該当するデータに対して言及することになるよ。
このとき、絞った結果が単一の要素でないとき、これまた失敗するよ。
チェスト等だとSlotは原理的に被ることはないから問題ないけど、
countとかで絞ってしまうと被ることが多々あるから、データが取りたいときは避けるべきだね。
やったぜ。
やった!これでデータの取得に関しては完璧だ!
アプデで新しいアイテムが増えたらまずdata get!!
カスタムアイテムの挙動が怪しいときもdata get!!!
なにか作りたいけど何も案がないときもdata get!!!!
皆様に置かれましてもよきdata getライフを。
あとがき
どうも、ゆきだよ。
用語解説のおまけを書いていたらなんか規模が大きくなりましたので、別トピックとして投稿させていただきます。
向こうの流れをくんでいる(?)ので、こちらも初学者向けの側面が強いですが、中級↑なのにも関わらず習得できていない人が身内にいたのでまとめてみました。
ノリが軽いのはおまけだったから崩しちゃえってことですネ。
こっちはスーパーフランクで。
んでもって結構思いつきで書いちゃったから抜け落ちてる要素もあるかもしれないので、思いついたり連絡が合ったりしたら追記するかもしれません。
変な部分があれば何卒お願いしますネ。m ^ _ ^ m (<- 土下座している単眼猫)
それでは改めて良きコマンドライフを。^👁️^ノシ