2017-02-11 79 views
1

我有这段代码用于迭代数组playerForm无法遍历此字典并将其组织成自定义结构

playerForm包含阵列中每个玩家的数组数量,并包含每个玩家的表单。

["playerForm": { 
1 =  (
      { 
     date = "2017-01-31"; 
     name = Dicky; 
     result = L; 
     "results_id" = 42; 
    }, 
      { 
     date = "2017-01-26"; 
     name = Dicky; 
     result = L; 
     "results_id" = 41; 
    } 
); 
2 =  (
      { 
     date = "2017-01-25"; 
     name = G; 
     result = W; 
     "results_id" = 38; 
    }, 
      { 
     date = "2017-01-25"; 
     name = G; 
     result = D; 
     "results_id" = 40; 
    } 
3 =  (
      { 
     date = "2017-01-31"; 
     name = Sultan; 
     result = W; 
     "results_id" = 42; 
    }, 
      { 
     date = "2017-01-26"; 
     name = Sultan; 
     result = W; 
     "results_id" = 41; 
    } 
    ); 
    }] 

这是我想使用的代码:

let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject] 
        print (json!) 

        if let dict = json?["playerForm"] as? [String:Any] { 

         print ("step 1") 

         for value in dict { 
          if let arr = value as? [[String:Any]] { 
           print(arr) 
           self.leagueForm = arr.flatMap { Form($0) } 

           for form in self.leagueForm { 
            self.formGuide.append(form.player_result!) 
           } 
           print ("break") 

          } 
         } 


         print (self.formGuide) 
        } 

这是我自定义的结构来组织数据;

struct Form { 
    var player_result: String? 
    var player_name: String? 
    var result_date: String? 
    var result_id: String? 

    init(_ dictionary: [String : Any]) { 
     self.player_result = dictionary["result"] as? String ?? "" 
     self.player_name = dictionary["name"] as? String ?? "" 
     result_date = dictionary["date"] as? String ?? "" 
     result_id = String(dictionary["results_id"] as? Int ?? 0) 


    } 
} 

var leagueForm = [Form]() 

但是,我收到警告:Cast from '(key: String, value: AnyObject)' to unrelated type [[String : Any]] always fails

这是我的PHP脚本提供初始阵列:

$noPlayers = count($communityPlayersIds); // 
$playerForm = array(); 
$playerForm = $dao->getCommunityForm($communityId, $noPlayers, $communityPlayersIds); 

public function getCommunityForm($communityId, $noPlayers, $communityPlayersIds){ 
$sql = " SELECT IF(player1_id=?, player1_result, player2_result) AS result, IF(player1_id=?, player1_name, player2_name) AS name, date, results_id FROM `results` WHERE (player1_id=? OR player2_id=?) AND community_id=? ORDER BY date DESC Limit 8"; 
$stmt = $this->conn->prepare($sql); 
$i = 0; 
foreach ($communityPlayersIds as $cPI) { 
    $i++; 
    $stmt->bind_param("iiiii", $cPI, $cPI, $cPI, $cPI, $communityId); 
    $stmt->execute(); 
    if ($result = $stmt->get_result()) { 
     while($row = $result->fetch_array(MYSQLI_ASSOC)){ 
      $returnValue[$i][] = $row; 
      } 
     } 
    }return $returnValue; 
} 

echo json_encode (array('playerForm' => $playerForm)); 

所以这个1,2,3在上面的例子是我怎么也收录从MySQL返回的结果。我这样做是为了分离数据,这样我就可以在Swift中构建它了。

我在哪里出错了?

+0

您可以显示JSON通过SWIFT而不是PHP打印出来? – johnslay

+0

Hi @johnslay是通过Swift打印的JSON ... – RDowns

+0

确定,并且正在打印出'第1步',还是无法投射并输入范围以打印出来? – johnslay

回答

0

你没有正确解开你的JSON。 json["playerForm"]是一个字典数组,而不是字典。试试这个:

let json = try! JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as! [String: Any] 
var leagueForm = [Form]() 

if let forms = json["playerForm"] as? [[String: Any]] { 
    leagueForm = forms.flatMap { Form($0) } 
} 

我认为这是你的样品JSON:

{ 
    "playerForm": [ 
     {"result": "L", "name": "Dicky", "date": "2017-02-10", "results_id": 48}, 
     {"result": "L", "name": "Dicky", "date": "2017-02-10", "results_id": 47}, 
     {"result": "L", "name": "Dicky", "date": "2017-02-09", "results_id": 44}, 
     {"result": "L", "name": "Dicky", "date": "2017-01-16", "results_id": 32}, 
     {"result": "D", "name": "Dicky", "date": "2016-12‌​-12", "results_id": 4}, 
     {"result": "W", "name": "Dicky", "date": "2016-12-12", "results_id": 6}, 
     {"result": "W", "name": "Dicky", "date": "2016-12-12", "results_id": 8} 
    ] 
} 
0

当您使用value in dict swift返回两条信息:一个键和一个值。因此,一般比较公认的办法是做这样的事情:

for (key, value) in dict ... 

如果预测,对于每个字典项的值将是[[String: Any]]类型的话,我建议做这样的事情:

for (_, value) in dict { 
    if let dictValue = value as? [[String:Any]] { 
     //do the rest with this value 
    } 

} 

请注意,您可以为关键变量名称加上下划线,因为您不打算使用它,因此您不需要将其存储在内存中。

当然,这并不能保证你的代码现在可以工作,但它应该解决这个特定的问题。

+0

嗨@BenjaminLowry,感谢您的回答 - 有趣的是,我最初的结构是这样的,但我仍然无法实现我在Swift中构建数据的目标。我向Stack Overflow发布了一个问题,并按照解决方案更改为此代码。我用更多的信息更新了这个问题。干杯 – RDowns

+0

@RDowns好吧,我查看了你的更新问题,但即使你的JSON格式不正确,也不能真正改变你有这个铸造问题的事实。我只是看着你的其他问题,甚至回答者也建议你这样做。当你实施这个解决方案时有什么问题? –

+0

这让我想到了某个点,但是我在分解数组时遇到了问题。我发布了这个问题: http://stackoverflow.com/questions/42039859/how-to-split-this-array-up-into-separate-elements-arrays-to-use-in-table-in-sw/42095029?noredirect = 1#comment71360571_42095029 然后底部的答案建议我改变那段代码 - 这就是我现在的位置。 – RDowns

1

我觉得你的问题是在这行代码

if let arr = value as? [[String:Any]] { 

看你的JSON文件,我可以看到你的JSON对象的格式如下:

["playerForm": { 
1 =  (
      { 
     date = "2017-01-31"; 
     name = Dicky; 
     result = L; 
     "results_id" = 42; 
    }, 
      { 
     date = "2017-01-26"; 
     name = Dicky; 
     result = L; 
     "results_id" = 41; 
    } 
);... 

所以,你的JSON根对象是一个[String:Any]字典,你正在做的是正确的。字典只有一个(键,值)对,键为'PlayerForm'。之后,你假设该对的值是[[String:Any]]的类型,这将是一个字典数组数组,我认为它不是:) 我认为这部分:

2 =  (
      { 

是从JSON文件有点故障,我不太清楚,以什么“2 =”应常备的,但它不是一个数组,数组不包含关键,像“ 1,2,3 ......“。

我建议铸造值别的东西,也许尝试

东西=价值? [字符串:任何]

如果这样的话,那么你可以将该字典中的值转换为NSArray进行迭代。

刚玩的铸有一段时间了:)

+0

Thankyou @Florens。我已经为您提供了我的PHP函数和MySQL Query,以向您展示1,2,3是什么。也许这是我出错的地方? – RDowns

+0

对不起,我对PHP知之甚少。你有没有尝试将值转换为别的东西,而不是[[String:Any]]? – Florensvb

+0

是的,我收到了类似的警告。无论如何感谢您的:) – RDowns