无法遍历此字典并组织成自定义Struct

时间:2017-02-11 13:44:17

标签: php ios arrays swift dictionary

我有这段代码用于迭代数组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来组织数据;

 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

中构建它

我哪里错了?

3 个答案:

答案 0 :(得分: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”#39;。之后你假设该对的值是[[String:Any]]类型,这将是一个字典数组的数组,我不认为它是:) 我认为这部分:

2 =     (
            {

从JSON文件中有点不对,我不太确定" 2 ="应该代表,但它不是一个数组,因为数组不包含键,如" 1,2,3 ..."。

我建议将值转换为其他内容,也许可以尝试

某物=价值如何? [String:Any]

如果有效则可以将该字典中的值转换为NSArray进行迭代。

只需在那里玩演员一段时间:)

答案 1 :(得分: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
    }

}

注意,您可以为密钥变量名称加下下划线,因为您不会使用它,因此您不需要将其存储在内存中。

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

答案 2 :(得分:0)

您没有正确打开JSON。 RxTextView .textChangeEvents(fuel_price) // Observe text event changes .filter { it.text().isNotEmpty() } // do not accept empty text when event first fires .flatMap { val onlyNumbers = Regex("\\d+").findAll(it.text()).fold(""){ acc:String,it:MatchResult -> acc.plus(it.value)} Observable.just(onlyNumbers) } .distinctUntilChanged() .map { it.trimStart('0') } .map { when (it.length) { 1-> "00"+it 2-> "0"+it else -> it } } .subscribe { val digitList = it.reversed().mapIndexed { i, c -> if ( i == 2 ) "${c}," else if ( i < 2 ) c else if ( (i-2)%3==0 ) "${c}." else c } val currency = digitList.reversed().fold(""){ acc,it -> acc.toString().plus(it) } fuel_price.text = SpannableStringBuilder(currency) fuel_price.setSelection(currency.length) } 是一个字典数组,而不是字典。试试这个:

json["playerForm"]

我认为这是你的样本JSON:

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) }
}