Changeset 868


Ignore:
Timestamp:
05/01/19 13:32:11 (5 years ago)
Author:
Maciej Komosinski
Message:

Added two methods for dictionary iteration: for(x in dict) and for(x in dict.keys)

Location:
cpp/frams/vm/classes
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/vm/classes/collectionobj.cpp

    r858 r868  
    5050ParamEntry dictionary_paramtab[] =
    5151{
    52         { "Dictionary", 1, 12, "Dictionary", "Dictionary associates stored values with string keys "
     52        { "Dictionary", 1, 14, "Dictionary", "Dictionary associates stored values with string keys "
    5353        "(\"key\" is the first argument in get/set/remove functions). Integer key can be "
    5454        "used to enumerate all elements (note that while iterating, the elements are returned in no particular order).\n"
     
    6565        "\td={ \"name\":\"John\", \"age\":44 };\n"
    6666        "Iterating:\n"
    67         "\tfor(var i=0;i<d.size;i++) Simulator.print(d.getKey(i)+\" is \"+d.get(i));",
     67        "\tfor(var v in d) Simulator.print(v); //values\n"
     68        "\tfor(var k in d.keys) Simulator.print(k+\" is \"+d[k]); //keys\n"
     69        "\tfor(var i=0;i<d.size;i++) Simulator.print(d.getKey(i)+\" is \"+d.get(i)); //by index",
    6870        },
    6971        { "clear", 0, PARAM_NOSTATIC, "Clear data", "p()", PROCEDURE(p_clear), },
     
    8486        { "clone", 0, PARAM_NOSTATIC, "Create a clone", "p oDictionary()", PROCEDURE(p_clone), "The resulting clone is a shallow copy (contains the same object references as the original). A deep copy can be obtained through serialization: String.deserialize(String.serialize(object));" },
    8587        { "assign", 0, PARAM_NOSTATIC, "Assign from another object", "p(x)", PROCEDURE(p_assign), "Replaces current dictionary with dictionary contents from another object." },
     88        { "iterator", 0, PARAM_NOSTATIC | PARAM_READONLY, "Iterator", "o", GETONLY(iterator), },
     89        { "keys", 0, PARAM_NOSTATIC | PARAM_READONLY, "Keys", "o", GETONLY(keys), "Iterate over this object to get all keys: for(k in dict.keys) ..." },
    8690
    8791        { 0, 0, 0, },
     
    539543}
    540544
     545void DictionaryObject::get_iterator(ExtValue* ret)
     546{
     547        ret->setObject(DictionaryIterator::makeFrom(this));
     548}
     549
     550void DictionaryObject::get_keys(ExtValue* ret)
     551{
     552        ret->setObject(DictionaryIterator::makeFrom(this));
     553}
     554
    541555////////////////
    542556
     
    584598}
    585599
     600/////////////////
     601
     602#define FIELDSTRUCT DictionaryIterator
     603ParamEntry dictionaryiterator_paramtab[] =
     604{
     605        { "DictionaryIterator", 1, 3, "DictionaryIterator", "DictionaryIterator" },
     606        { "next", 0, PARAM_READONLY | PARAM_NOSTATIC, "next", "d 0 1", GETONLY(next), },
     607        { "value", 0, PARAM_READONLY | PARAM_NOSTATIC, "value", "x", GETONLY(value), },
     608        { "iterator", 0, PARAM_READONLY | PARAM_NOSTATIC, "keys iterator", "x", GETONLY(iterator), },
     609        { 0, 0, 0, },
     610};
     611#undef FIELDSTRUCT
     612
     613DictionaryIterator::DictionaryIterator(DictionaryObject* d, bool _keys)
     614        :it(d->hash)
     615{
     616        dic = d;
     617        dic->incref();
     618        initial = true;
     619        keys = _keys;
     620}
     621
     622ExtObject DictionaryIterator::makeFrom(DictionaryObject *d, bool _keys)
     623{
     624        static Param par(dictionaryiterator_paramtab);
     625        return ExtObject(&par, new DictionaryIterator(d, _keys));
     626}
     627
     628DictionaryIterator::~DictionaryIterator()
     629{
     630        dic->decref();
     631}
     632
     633void DictionaryIterator::get_next(ExtValue* ret)
     634{
     635        if (initial)
     636                initial = false;
     637        else
     638                it++;
     639        ret->setInt(it.isValid());
     640}
     641
     642void DictionaryIterator::get_value(ExtValue* ret)
     643{
     644        if ((!initial) && it.isValid())
     645        {
     646                if (keys)
     647                {
     648                        ret->setString(it->key);
     649                }
     650                else
     651                {
     652                        ExtValue *v = (ExtValue*)it->value;
     653                        if (v == NULL)
     654                                ret->setEmpty();
     655                        else
     656                                *ret = *v;
     657                }
     658        }
     659        else
     660                ret->setEmpty();
     661}
     662
     663void DictionaryIterator::get_iterator(ExtValue* ret)
     664{
     665        ret->setObject(makeFrom(dic, true));
     666}
     667
     668//////////////
     669
    586670// not actually needed for deserialization (vector and dict are special cases) but findDeserializableClass can be also used in other contexts
    587671REGISTER_DESERIALIZABLE(VectorObject)
  • cpp/frams/vm/classes/collectionobj.h

    r849 r868  
    7979        PARAMPROCDEF(p_clone);
    8080        PARAMPROCDEF(p_assign);
     81        PARAMGETDEF(iterator);
     82        PARAMGETDEF(keys);
    8183#undef STATRICKCLASS
    8284        ExtValue get(SString key);
     
    107109};
    108110
     111class DictionaryIterator : public DestrBase
     112{
     113public:
     114        DictionaryObject *dic;
     115        HashEntryIterator it;
     116        bool initial, keys;
     117        DictionaryIterator(DictionaryObject* d, bool _keys);
     118        ~DictionaryIterator();
     119#define STATRICKCLASS DictionaryIterator
     120        PARAMGETDEF(next);
     121        PARAMGETDEF(value);
     122        PARAMGETDEF(iterator);
     123#undef STATRICKCLASS
     124        static ExtObject makeFrom(DictionaryObject *v, bool _keys = false);
     125};
     126
    109127#endif
Note: See TracChangeset for help on using the changeset viewer.