计算 JSON 数组中的元素,该数组位于对象中

发布于 2025-01-08 18:16:36 字数 4836 浏览 0 评论 0原文

我有一个纯粹的 ActionScript 3 问题,但我准备的简化测试用例是在 Flex 4 中以获得更好的可见性(源代码如下):

在此处输入图像描述

由于 Flash Player 11 / AIR 3 本身支持 JSON,因此我决定将使用 XML 与服务器通信的多人游戏迁移到 JSON。

但我有一个令人沮丧的问题,给定两个对象,就像

                { 9013: [
                    "OK305894249541",
                    "OK151358069597",
                    "OK515549948434",
                ] },
                { 8991: [
                    "OK253525117889",
                    "OK529081480134",
                ] },

我不知道如何创建 ActionScript 函数,该函数会为第一个对象报告 3,为第二个对象报告 2?

“9013”上例中的“8991”是游戏号码。

“OKxxxx”字符串代表玩家。

当游戏有 3 名玩家时,游戏为“满员”,否则为“空缺”。

这是我非常简单的 TestCase.mxml

<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationComplete="init(event)">

    <fx:Declarations>
        <s:RadioButtonGroup id="_filter" change="handleRadio(event);" />
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;

            [Bindable]
            private var _games:ArrayCollection = new ArrayCollection();

            [Bindable]
            private var _all:uint = 0;

            [Bindable]
            private var _vac:uint = 0;

            [Bindable]
            private var _full:uint = 0;

            private function vacantGame(obj:Object):Boolean {
                // XXX how to implement?
                // XXX return true if obj has less than 3 players
                return true;
            }

            private function fullGame(item:Object):Boolean {
                // XXX how to implement?
                // XXX return true if obj has exactly 3 players
                return true;
            }

            private function init(event:FlexEvent):void {
                var i:uint;

                _games.source = OBJ['games'];

                _all = _games.length;

                _vac = 0;
                for (i = 0; i < _games.length; i++)
                    if (vacantGame(_games[i]))
                        _vac++;

                _full = 0;
                for (i = 0; i < _games.length; i++)
                    if (fullGame(_games[i]))
                        _full++;
            }

            private function handleRadio(event:Event):void {
                switch (_filter.selection) {
                    case _allBtn:
                        _games.filterFunction = null; 
                        break;
                    case _vacBtn:
                        _games.filterFunction = vacantGame;
                        break;
                    case _fullBtn:
                        _games.filterFunction = fullGame;
                        break;
                }
                _games.refresh();
            }

            private const OBJ:Object = {
                lobby: [
                    "OK108900197210",
                    "OK266559712237",
                    "DE6577",
                    "DE7981",
                    "OK225312168135",
                    "OK20629248715",
                    "DE7880",
                ],
                games: [
                    { 0: [] },
                    { 9012: [
                        "VK48058967",
                        "MR14315189992643135976",
                        "OK10218913103",
                    ] },
                    { 9013: [
                        "OK305894249541",
                        "OK151358069597",
                        "OK515549948434",
                    ] },
                    { 8991: [
                        "OK253525117889",
                        "OK529081480134",
                    ] },
                    { 8937: [
                        "OK304672497140",
                        "VK90145027",
                        "OK338360548262",
                    ] },
                    { 9005: [
                        "OK40798070412",
                        "DE7979",
                        "OK531589632132",
                    ] },
                    { 9010: [
                        "OK357833936215",
                    ] },
                ]
            };
        ]]>
    </fx:Script>

    <s:HGroup verticalAlign="baseline">
        <s:Label text="Games:" />
        <s:RadioButton id="_allBtn" group="{_filter}" label="All: {_all}" selected="true" />
        <s:RadioButton id="_vacBtn" group="{_filter}" label="Vacant: {_vac}" />
        <s:RadioButton id="_fullBtn" group="{_filter}" label="Full: {_full}" />
    </s:HGroup>
</s:Application>

I have a pure ActionScript 3 problem, but the simplified test case I've prepared is in Flex 4 for better visibility (the source code is below):

enter image description here

Since Flash Player 11 / AIR 3 support JSON natively, I've decided to move a multiplayer game, which used XML for communicating with server, to JSON.

But I have a frustrating problem, that given two Objects like

                { 9013: [
                    "OK305894249541",
                    "OK151358069597",
                    "OK515549948434",
                ] },
                { 8991: [
                    "OK253525117889",
                    "OK529081480134",
                ] },

I don't know how to create an ActionScript function, which would report 3 for the first Object and 2 for the second Object?

The "9013" and "8991" in the example above are game numbers.

The "OKxxxx" strings represent players.

A game is "full" when it holds 3 players, "vacant" otherwise.

Here is my very simple TestCase.mxml:

<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationComplete="init(event)">

    <fx:Declarations>
        <s:RadioButtonGroup id="_filter" change="handleRadio(event);" />
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;

            [Bindable]
            private var _games:ArrayCollection = new ArrayCollection();

            [Bindable]
            private var _all:uint = 0;

            [Bindable]
            private var _vac:uint = 0;

            [Bindable]
            private var _full:uint = 0;

            private function vacantGame(obj:Object):Boolean {
                // XXX how to implement?
                // XXX return true if obj has less than 3 players
                return true;
            }

            private function fullGame(item:Object):Boolean {
                // XXX how to implement?
                // XXX return true if obj has exactly 3 players
                return true;
            }

            private function init(event:FlexEvent):void {
                var i:uint;

                _games.source = OBJ['games'];

                _all = _games.length;

                _vac = 0;
                for (i = 0; i < _games.length; i++)
                    if (vacantGame(_games[i]))
                        _vac++;

                _full = 0;
                for (i = 0; i < _games.length; i++)
                    if (fullGame(_games[i]))
                        _full++;
            }

            private function handleRadio(event:Event):void {
                switch (_filter.selection) {
                    case _allBtn:
                        _games.filterFunction = null; 
                        break;
                    case _vacBtn:
                        _games.filterFunction = vacantGame;
                        break;
                    case _fullBtn:
                        _games.filterFunction = fullGame;
                        break;
                }
                _games.refresh();
            }

            private const OBJ:Object = {
                lobby: [
                    "OK108900197210",
                    "OK266559712237",
                    "DE6577",
                    "DE7981",
                    "OK225312168135",
                    "OK20629248715",
                    "DE7880",
                ],
                games: [
                    { 0: [] },
                    { 9012: [
                        "VK48058967",
                        "MR14315189992643135976",
                        "OK10218913103",
                    ] },
                    { 9013: [
                        "OK305894249541",
                        "OK151358069597",
                        "OK515549948434",
                    ] },
                    { 8991: [
                        "OK253525117889",
                        "OK529081480134",
                    ] },
                    { 8937: [
                        "OK304672497140",
                        "VK90145027",
                        "OK338360548262",
                    ] },
                    { 9005: [
                        "OK40798070412",
                        "DE7979",
                        "OK531589632132",
                    ] },
                    { 9010: [
                        "OK357833936215",
                    ] },
                ]
            };
        ]]>
    </fx:Script>

    <s:HGroup verticalAlign="baseline">
        <s:Label text="Games:" />
        <s:RadioButton id="_allBtn" group="{_filter}" label="All: {_all}" selected="true" />
        <s:RadioButton id="_vacBtn" group="{_filter}" label="Vacant: {_vac}" />
        <s:RadioButton id="_fullBtn" group="{_filter}" label="Full: {_full}" />
    </s:HGroup>
</s:Application>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绮烟 2025-01-15 18:16:36

正确的答案是重新考虑您的数据结构。
抛开周围的数组,反正所有游戏都有唯一的ID。

但如果你坚持像上面那样使用,你可以这样做:

private function vacantGame(obj:Object):Boolean{
    for( var gameNumber : String in obj ){
        var players : Array = obj[ gameNumber ]
        return players.length < 3
    }
    return false;
}

更好的方法:

games: {
    0: [],
    9012: [
        "VK48058967",
        "MR14315189992643135976",
        "OK10218913103",
    ],
    9013: [
        "OK305894249541",
        "OK151358069597",
        "OK515549948434",
    ],
    ...
}

那么

for( var gameNumber : String in OBJ.games ){
    var players : Array = OBJ.games[ gameNumber ];
    if( players.length < 3 ){
        //vacant
    }else{
        //full
    }
}

The right answer is to rethink your data structure.
Drop the surrounding array, all games have a unique ID anyway.

But if you insist on using it as above, you can do the following:

private function vacantGame(obj:Object):Boolean{
    for( var gameNumber : String in obj ){
        var players : Array = obj[ gameNumber ]
        return players.length < 3
    }
    return false;
}

The better way:

games: {
    0: [],
    9012: [
        "VK48058967",
        "MR14315189992643135976",
        "OK10218913103",
    ],
    9013: [
        "OK305894249541",
        "OK151358069597",
        "OK515549948434",
    ],
    ...
}

then

for( var gameNumber : String in OBJ.games ){
    var players : Array = OBJ.games[ gameNumber ];
    if( players.length < 3 ){
        //vacant
    }else{
        //full
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文