Автоматические инструменты могут быть очень полезными, но они не идеальны - особенно когда речь заходит о словарях.
Первое, что нужно отметить, это то, что структура одинакова для всех из них, то есть все они состоят из свойств hash
и size
. Это означает, а не создание сотен одинаковых классов, мы можем использовать один и тот же один снова и снова:
' the type that repeats from your robot:
Public Class MinecraftItem
Public Property hash As String
Public Property size As Int32
End Class
Поскольку автоматические инструменты работают «на лету» (они не смотрят вперед ... или назад) они не знают, что они все одинаковые. Следующее, что классы, созданные роботами, не будут работать в этом случае:
Public Property minecraft/sounds/music/game/creative/creative3.ogg As _
MinecraftSoundsMusicGameCreativeCreative3Ogg
Это незаконно как имя свойства. Тем не менее, имена будут работать отлично, как словарные ключи. В дополнение к указанному выше классу MinecraftItem
мы могли бы хотеть класс контейнера:
Public Class MinecraftContainer
Public objects As Dictionary(Of String, MinecraftItem)
End Class
Существует (по крайней мере) 3 способа получить данные:
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Dim jstr As String = ...from whereever
' parse the json into a JObject
Dim js As JObject = JObject.Parse(jstr)
' if you somehow know the names, you can pluck out the data:
Dim mi = js("objects")("minecraft/sounds/mob/blaze/hit2.ogg")
Console.WriteLine(mi("hash").ToString & " " & mi("size").ToString)
Первая строка анализирует исходную строку json в JObject. Это позволяет нам работать с содержимым различными способами. Например, мы можем ссылаться на «объекты» в json и на них элементы по имени, что и происходит в следующей строке:
' drill into "objects", get the "...hit2.ogg" item
Dim mi = js("objects")("minecraft/sounds/mob/blaze/hit2.ogg")
Это будет работать, если вам просто нужно получить конкретную элемент из большого файла. Созданная переменная mi
представляет собой «специальный» токен json, поэтому используйте имена, чтобы получить нужные биты данных.
hash = mi("hash").ToString
size = mi("size").ToString
будет мой предпочтительный метод. Включите те же Import
операторы, что и в первом примере, затем:
' parse the json string
Dim js As JObject = JObject.Parse(jstr)
' deserialize the inner "objects" to a NET Dictionary
Dim myItems = JsonConvert.DeserializeObject(Of Dictionary(Of String, _
MinecraftItem))(js("objects").ToString)
Это создаст myItems
как сеть Dictionary(Of String, MincraftItem)
из json. Поскольку класс MinecraftObject
не делает ничего , но держит словарь, мы его пропустили.
Ключами являются длинные имена, а каждое значение - MinecraftItem
, что позволяет ссылаться на них более условно:
' get one of the items into a variable
gravel3 = myItems("minecraft/sounds/mob/chicken/step2.ogg")
ConsoleWriteLine("Gravel3 hash: {0}, size: {1}",
gravel3.hash, gravel3.size.ToString)
Если вы не знакомы с .Net Dictionary он несколько похож на массив или список, за исключением того, что вы обращаетесь к своим элементам с помощью Key
, а не индекса. Чтобы перебрать их все:
Dim n As Integer = 0
For Each kvp As KeyValuePair(Of String, MinecraftItem) In myItems
Console.WriteLine("Name: {0} Hash: {1} size: {2}",
kvp.Key,
kvp.Value.hash,
kvp.Value.size.ToString)
n += 1
If n >= 2 Then Exit For ' just print 3
Next
Выход:
Имя: realms / lang / de_DE.lang Хэш: 10a54fc66c8f479bb65c8d39c3b62265ac82e742 Размер: 8112 Имя: realms / lang / cy_GB .lang Хэш: 14cfb2f24e7d91dbc22a2a0e3b880d9829320243 Размер: 7347 Имя: minecraft / sounds / mob / chicken / step2.ogg Хэш: bf7fadaf64945f6b31c803d086ac6a652aabef9b Размер: 3838
blockquote>Просто помните, что ключ всегда будет длинным путем , и каждый
.Value
является объектомMinecraftItem
.Метод 3: Deserialize To Container
Вы можете пропустить шаг синтаксического анализа, используя кнопку
MinecraftContainer
class:Dim jstr As String = ...from whereever Dim myJItems = JsonConvert.DeserializeObject(Of MinecraftContainer)(jstr)
Обратите внимание, что на этот раз вы передаете всю строку, которую вы загрузили , на
JsonConvert
. Результатом будет дополнительный внешний объект, который содержит свойство словаря с именем «Объекты». Таким образом, вы ссылаетесь на элементы, используя некоторые ведущие ссылки:gravel3hash = myJItems.Object("minecraft/sounds/dig/gravel3.ogg").hash gravel3 = myJItems.Object("minecraft/sounds/dig/gravel3.ogg") ConsoleWriteLine("Gravel3 hash: {0}, size: {1}", gravel3.hash, gravel3.size.ToString) 'or: ConsoleWriteLine("Gravel3 hash: {0}, size: {1}", myJItems.Object("minecraft/sounds/dig/gravel3.ogg").hash, myJItems.Object("minecraft/sounds/dig/gravel3.ogg").size.ToString)
Этот метод представляет собой только одну строку кода для десериализации, но это означает: a) я должен определить класс контейнера и b) мне нужно используйте
myJItems.Object
, чтобы просверлить в противном случае пустой контейнер, чтобы попасть в словарь.Лично я бы отказался от этого и использовал метод 2 - одна дополнительная строка кода упрощает работу с ним. Тем не менее, вы также можете извлечь коллекцию словаря из контейнера:
Dim myItems As Dictionary(Of String, MinecraftItem)= myJItems.Object
Да в конфигурации ticks.fontSize вы можете сделать это только для оси x. Например,
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
fontSize: 8
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>