我有一个JSON结果我试图在AppleScript中使用,但由于顶级项目是“未命名”,我只能通过管道项目引用访问它们,在这种情况下是一个数字。因此,我无法迭代它,它必须硬编码(向下滚动到最后一个代码示例,看看我的意思)
例如,这是我正在看的JSON:
{
"1": {
"name": "Tri 1"
},
"2": {
"name": "Tri 2"
},
"3": {
"name": "Tri 3"
},
"4": {
"name": "Orb Dave"
},
"5": {
"name": "Orb Fah"
}
}
在JSON Helper的帮助下,我将JSON变为更有用的格式(对于AppleScript)。
{|3|:{|name|:"Tri 3"}, |1|:{|name|:"Tri 1"}, |4|:{|name|:"Orb Dave"}, |2|:{|name|:"Tri 2"}, |5|:{|name|:"Orb Fah"}}
然后,我可以使用此代码获取相关对象的“灯光”列表:
set lights to (every item in theReturn) as list
repeat with n from 1 to count of lights
set light to item n of lights
log n & light
end repeat
由此,我得到:
(*1, Tri 3*)
(*2, Tri 1*)
(*3, Orb Dave*)
(*4, Tri 2*)
(*5, Orb Fah*)
您可能会注意到结果未按所需顺序排列。索引是灯光列表中的索引。它不是出现在对象顶部的数字。如果您查看前两个预先形成的区域,您会看到项目1,2和3分别是Tri 1,Tri 2和Tri 3. Tri 3首先出现,Tri 1秒和Orb是正确的。排名第三。
我需要做的是找到一种方法能够以任何顺序迭代JSON(排序与否)并能够将“1”与“Tri 1”,“3”与“Tri 3”排成一行“和”5“与”Orb Fah“。但我找不到任何与返回的JSON交互的方法,它允许我引用第三个灯并返回它的名字。我似乎能够做到的唯一方法是对光索引进行硬编码,例如:
log |name| of |1| of theReturn
log |name| of |2| of theReturn
log |name| of |3| of theReturn
log |name| of |4| of theReturn
log |name| of |5| of theReturn
给了我正确名称的正确光线:
(*Tri 1*)
(*Tri 2*)
(*Tri 3*)
(*Orb Dave*)
(*Orb Fah*)
我认为问题出现了,因为灯光ID没有描述符或排序。我无法改变,但我需要以编程方式迭代它们。如上所述对其进行硬编码是不可接受的。
任何帮助将不胜感激
答案 0 :(得分:2)
您正在处理此处的记录列表,而不是列表列表。记录是键/值对。它们没有列表之类的索引。如果你知道钥匙就很容易,因为你只需要一个你想要的钥匙。并且您的记录中包含记录,因此您有2层记录。因此,如果您想要| name |的值记录对应于| 3 |记录,然后你发现了......
set jsonRecord to {|3|:{|name|:"Tri 3"}, |1|:{|name|:"Tri 1"}, |4|:{|name|:"Orb Dave"}, |2|:{|name|:"Tri 2"}, |5|:{|name|:"Orb Fah"}}
set record3name to |name| of |3| of jsonRecord
AppleScript中记录的缺点是没有命令来查找记录键。其他编程语言为您提供了查找键的工具(如objective-c),但AppleScript却没有。你必须提前知道它们,并在我展示时使用它们。
如果您不提前知道密钥,那么您可以使用JSON Helper以不同的形式提供结果,或使用不同的编程语言(python,ruby等)从记录中提取信息
另一个选择是在不使用JSON Helper的情况下使用json文本。例如,如果您将json作为文本,那么您可以使用标准的AppleScript命令为文本对象提取信息。你的json文本在第3行,6日,9日等都有你想要的信息。你可以利用它来做你的优势并做这样的事情......
set jsonText to "{
\"1\": {
\"name\": \"Tri 1\"
},
\"2\": {
\"name\": \"Tri 2\"
},
\"3\": {
\"name\": \"Tri 3\"
},
\"4\": {
\"name\": \"Orb Dave\"
},
\"5\": {
\"name\": \"Orb Fah\"
}
}"
set jsonList to paragraphs of jsonText
set namesList to {}
set AppleScript's text item delimiters to ": \""
repeat with i from 3 to count of jsonList by 3
set theseItems to text items of (item i of jsonList)
set end of namesList to text 1 through -2 of (item 2 of theseItems)
end repeat
set AppleScript's text item delimiters to ""
return namesList
答案 1 :(得分:2)
对于每个索引,遍历列表中的所有项目,查找名称与索引匹配的项目:
tell application "System Events"
-- Convert the JSON file to a property list using plutil.
do shell script "plutil -convert xml1 /Users/mxn/Desktop/tri.json -o /Users/mxn/Desktop/tri.plist"
-- Read in the plist
set theItems to every property list item of property list file "/Users/mxn/Desktop/tri.plist"
set theLights to {}
-- Iterate once per item in the plist.
repeat with i from 1 to count of theItems
set theName to i as text
-- Find the item whose name is the current index.
repeat with theItem in theItems
if theItem's name is theName then
-- We found it, so add it to the results.
set theValue to theItem's value
copy {i, theValue's |name|} to the end of theLights
-- Move on to the next index.
exit repeat
end if
end repeat
end repeat
return theLights
end tell
结果:
{{1, "Tri 1"}, {2, "Tri 2"}, {3, "Tri 3"}, {4, "Orb Dave"}, {5, "Orb Fah"}}
理想情况下,我们可以这样说:
,而不是嵌套循环set theName to i as text
set theItem to (the first item in theItems whose name is theName)
但不幸的是,这会产生错误。
此解决方案还演示了JSON Helper的替代方法:您可以使用方便的plutil
命令行工具将JSON文件转换为属性列表,并使用系统事件'内置支持财产清单。