Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Сортировка двумерного масива, взятого из XML. (http://www.flasher.ru/forum/showthread.php?t=148867)

Punk T-34 13.01.2011 05:21

Сортировка двумерного масива, взятого из XML.
 
Здравствуйте!
Весь день сегодня рыл интернет и читал справочные материалы по .sort() и .sorOn(), но фактически, смотрел как баран на новые ворота.
Не получается сортировать двумерный массив сформированный в XML.

XML для примера. Задача — отсортировать товары по цене в порядке убывания:
Код:

<?xml version="1.0" ?>
<shop name="SuperMarket">
    <product name="Apple" price="13" type="food" />
    <product name="Juice" price="32" type="food" />
    <product name="Ball" price="45" type="other" />
    <product name="Bike" price="01" type="other" />
    <product name="Shirt" price="04" type="other" />
    <product name="Cup" price="32" type="other" />
    <product name="Phone" price="67" type="other" />
    <product name="Rice" price="11" type="food" />
    <product name="Pepper" price="06" type="food" />
    <product name="Toy" price="33" type="other" />
    <product name="Bag" price="90" type="other" />
    <product name="Turkey" price="86" type="food" />
</shop>

Способ №1:
Код AS1/AS2:

import com.xfactorstudio.xml.xpath.XPath;
var mycontent:XML;
mycontent = new XML();
mycontent.onLoad = function(success:Boolean):Void  {
    if (success) {
        var products:Array = XPath.selectNodes(mycontent, "shop/product/");
        var Name:Array = XPath.selectNodes(mycontent, "shop/product/@name");
        var Prices:Array = XPath.selectNodes(mycontent, "shop/product/@price");
 
        for (i = 0; i < products.length; i++) {
            normal.text += Prices[i] + " - " + Name[i] + "\n";
        }
        products.sortOn("price",Array.DESCENDING | Array.NUMERIC);
        //
        for (i = 0; i < products.length; i++) {
            sorted.text += Prices[i] + " - " + Name[i] + "\n";
        }
    }
};
mycontent.load("shop.xml");

Здесь массив products представляет из себя такую штуку:
http://my.jetscreenshot.com/359/m_20...-lveh-58kb.jpg

Сортировка не работает. Массивы до и после сортировки не отличаются. Результат:
http://my.jetscreenshot.com/359/m_20...-m2mv-25kb.jpg

Со вторым способом результат такой же. Кусок кода отвечающий за сортировку:
Код AS1/AS2:

function order(a, b):Number {
    var name1:String = a.attribute.price;
    var name2:String = b.attribute.price;
    if (name1 < name2) {
        return -1;
    } else if (name1 > name2) {
        return 1;
    } else {
        return 0;
    }
}
for (i = 0; i < products.length; i++) {
    normal.text += Prices[i] + " - " + Name[i] + "\n";
}
products.sort(order);
for (i = 0; i < products.length; i++) {
    sorted.text += Prices[i] + " - " + Name[i] + "\n";
}

Добавлено через 41 секунду
Что я делаю не так? Или что я не делаю?

mooncar 13.01.2011 10:14

Если массив products имеет вид, который у вас представлен на скрине, то sort и sortOn не будут работать, как вы ожидаете.
К тому же вы пытаетесь отсортировать products, а выводите значения из Prices и Name. Но это уже несущественно.

Решение без класса XPath:
Код AS1/AS2:

var products:Array = new Array();
var xmlData:XML = new XML();
xmlData.ignoreWhite = true ;
xmlData.onLoad = xmlDataOnLoad;
xmlData.load('shop.xml');
 
function xmlDataOnLoad(success:Boolean):Void 
{
        if (success)
        {               
                var node:XMLNode = this.firstChild ;
                var total:Number = node.childNodes.length ; //количество узлов
 
                for (i = 0; i < total; i++)
                {
                        //извлекаем значения атрибутов
                        var n:String = node.childNodes[i].attributes['name'];
                        var p:Number = parseInt(node.childNodes[i].attributes['price']);
                        //вносим в массив
                        products.push({name: n, price: p});
                }
 
                for (i = 0; i < products.length; i++)
                {
                        trace (products[i].price + ' - ' + products[i].name);
                }
 
                trace('-------');
 
                products.sortOn('price', Array.DESCENDING | Array.NUMERIC);
 
                for (i = 0; i < products.length; i++)
                {
                        trace (products[i].price + ' - ' + products[i].name);
                }
        }
}

Поскольку нужно "отсортировать товары по цене в порядке убывания", приводим значение атрибута "price" к числу с помощью parseInt, иначе бы сортировка велась по законам сортировки строчных значений.

Punk T-34 13.01.2011 17:25

Спасибо!
Окончательно разобрался и понял как это всё работает после того как, этим же способом, удачно отсортировал трехмерный массив.

Добавлено через 3 часа 2 минуты
Ещё вопрос:
Вот здесь я создаю новый массив (аналогичный xml):
Код AS1/AS2:

products.push({name: n, price: p});

и сортируем по атрибуту "price".
А что если я хочу записать в новый массив несуществующее значение и сортировать по нему?
Как это можно сделать?
Например:
Код AS1/AS2:

for (i = 0; i < total; i++) {
        var n:String = node.childNodes[i].attributes['name'];
        var p:Number = parseInt(node.childNodes[i].attributes['price']);
        var a:Number = parseInt(node.childNodes[i].attributes['priceA']);
        var b:Number = parseInt(node.childNodes[i].attributes['priceB']);
        var с:Number = a + b;
        products.push({name:n, price:p, sum:c});
}
products.sortOn('sum',Array.DESCENDING | Array.NUMERIC);

Вот так как в примере у меня не работает.


Часовой пояс GMT +4, время: 10:03.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.