다음 JSON이 있습니다.
{
"type": "champion",
"version": "6.24.1",
"data": {
"Jax": {
"id": 24,
"key": "Jax",
"name": "Jax",
"title": "Grandmaster at Arms",
"image": {
"full": "Jax.png",
"sprite": "champion1.png",
"group": "champion",
"x": 48,
"y": 48,
"w": 48,
"h": 48
}
},
"Sona": {
"id": 37,
"key": "Sona",
"name": "Sona",
"title": "Maven of the Strings",
"image": {
"full": "Sona.png",
"sprite": "champion3.png",
"group": "champion",
"x": 288,
"y": 0,
"w": 48,
"h": 48
}
}
}
}
RiotRequestManager는 문자열을 수집합니다. LeagueObjectManager 클래스에서 "full"및 "sprite"에 대한 이미지 문자열에 액세스 할 수 있기를 원합니다. 이름 목록을 얻고 방법을 제공하여 LeagueObject의 이름을 사용하여 이미지를 가져올 수 있기를 원했습니다. 목록에서 이름을 클릭하고 이미지 전체 문자열을 반환하려고합니다. 내가 시도하는 모든 것은 null 응답을 제공합니다.
다음과 같은 수업이 있습니다.
Imports Newtonsoft.Json
Public Class LeagueObjectManager
Private rrm As New RiotRequestManager
Private lc As LeagueObjectContainer
Private count As Integer
Public Sub New(ByVal strRegion As String, ByVal strMode As String)
lc = JsonConvert.DeserializeObject(Of LeagueObjectContainer)(rrm.returnLeagueItems(strRegion, strMode))
count = lc.data.Count()
End Sub
Public Function returnNames() As String()
Dim strReturn(count - 1) As String
Dim errorCount As Integer = 0
Dim counter As Integer = 0
For i = 0 To count - 1
If Not (lc.data.ElementAt(i).Value.name = "error") Then
strReturn(counter) = lc.data.ElementAt(i).Value.name
counter += 1
Else
errorCount += 1
ReDim Preserve strReturn(count - 1 - errorCount)
End If
Next
Return strReturn
End Function
End Class
Public Class LeagueObjectContainer
Public Property type As String
Public Property version As String
Public Property data As SortedDictionary(Of String, LeagueObject)
End Class
Public Class LeagueObject
Public Property id As Integer
Public Property key As String
Public Property name As String = "error"
Public Property title As String
Public Property image As SortedDictionary(Of String, LeagueImage)
Public Property group As String
Public Property tags As String()
Public Property enemytips As String
Public Property allytips As String
End Class
Public Class LeagueImage
Public Property full As String
Public Property sprite As String
End Class
보유하고있는 것에 적용 할 수있는 몇 가지 효율성이 있습니다. 주로 관리자 역할을하는 다른 클래스가 필요하지 않습니다. 추가하려는 메서드 나 추가 속성을 기존 클래스에 추가 할 수 있습니다. 좀 더 관용적 인 이름 사용 :
Public Class DataItem
Public Property id As Integer
Public Property key As String
Public Property name As String = ""
Public Property title As String
Public Property image As ImageInfo
Public Overrides Function ToString() As String
Return name
End Function
End Class
Public Class ImageInfo
Public Property full As String
Public Property sprite As String
Public Property group As String
Public Property x As Integer
Public Property y As Integer
Public Property w As Integer
Public Property h As Integer
End Class
관심이 없더라도 모든 이미지 속성을 그대로 두었습니다. 그런 다음 컨테이너 클래스는 컨테이너 및 관리자 클래스의 합체가 될 수 있습니다.
Public Class LeagueManager
Public Property type As String
Public Property version As String
Public Property data As Dictionary(Of String, DataItem)
Public Sub New()
End Sub
' could/should be As IEnumerable(Of String)
Public Function GetPlayerNames() As String()
' enumerate Values collection of dictionary,
' filter out those with no name
' select/pick/use the DataItem.name
' put them in alpha order
' convert from IEnumerable to an array
Dim names = data.Values.AsEnumerable().
Where(Function(j) String.IsNullOrEmpty(j.name) = False).
Select(Function(q) q.name).
OrderBy(Function(k) k).
ToArray()
Return names
End Function
Public Function GetPlayer(name As String) As DataItem
' first first DataItem where the names match
Return data.Values.
FirstOrDefault(Function(q) String.Compare(name, q.name, StringComparison.InvariantCultureIgnoreCase) = 0)
End Function
Public Function GetPlayers() As DataItem()
Return data.Values.AsEnumerable().Cast(Of DataItem).ToArray()
End Function
End Class
allytips
. 하나 이상의 json에 대해 하나의 클래스를 사용하려고합니까? 그렇다면 관리자와 컨테이너를 결합하지 않을 수도 있습니다.Dictionary
대신 일반 이 사용됩니다 SortedDictionary
. Dictionary
원하는 형태 나 순서로 원하는 것을 쉽게 얻을 수 있습니다 .ToString()
에 재정의 DataItem
디버깅에 유용합니다.관리자와 컨테이너를 결합하면 생성자에서 역 직렬화하지 마십시오. JSON.NET이 역 직렬화를 위해 또 다른 루프를 만들 때 무한 루프에 빠질 것이라고 생각합니다. 명시 적 Load 메서드를 사용하면 다른 매개 변수 / 지역 등에 대한 데이터를 (재)로드 할 수 있습니다.
GetPlayer(string)
방법을 반환 한 DataItem
곳에 이름 일치 (경우를 구분). 이것은 Dictionary
키 에 의존하지 않고 구현 DataItems
을 숨기는 실제 이름 에 의존 하지만 Nothing
항목을 제거 / 삭제할 수있는 경우 반환 될 수 있습니다.
Dim JaxData = myData.GetPlayer("jax")
If JaxData IsNot Nothing Then
...
End If
이것은에서 반환 된 이름을 사용하여 컬렉션을 반복하는 또 다른 방법을 제공합니다 GetPlayerNames()
. Count
, HasPlayer
그리고 필요한 다른 속성과 메서드를 추가 할 수 있습니다 . 이미지의 경우 DataItem의 또 다른 속성입니다.
Dim jstr = ...
Dim leagueData = JsonConvert.DeserializeObject(Of LeagueManager)(jstr)
' get array of names
Dim names = leagueData.GetPlayerNames()
Dim di As DataItem
For Each s As String In names
' get DataItem object for player named in 's'
di = leagueData.GetPlayer(s)
If di IsNot Nothing Then
Console.WriteLine("{0} aka '{1}' uses image: '{2}'", di.name,
di.title, di.image.sprite)
Else
' very unlikely:
Console.WriteLine("Cannot find {0}", s)
End If
Next
결과 :
Jax
Sona
Jax 일명 'Grandmaster at Arms'사용 이미지 : 'champion1.png'Sona
일명 'Maven of the Strings'사용 이미지 : 'champion3.png'
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다