www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5466] New: AA ranges

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5466

           Summary: AA ranges
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: druntime
        AssignedTo: sean invisibleduck.org
        ReportedBy: bearophile_hugs eml.cc



I use D associative arrays often so I'd like AAs to be modified so byKey() and
byValue() return ranges (that have a length attribute too) usable with higher
order functions of std.algorithm like map and filter.

AAs too may become iterable with no method calls:
map!q{a * 10}([1:2, 3:4])

I also suggest to add a third associative array member function that returns a
range of (key,value) typecons tuples, as in a similar Python3 dict method.

------------------

To test the situation, this task is to create a dynamic array of pairs (tuples)
like:
[(10,"aa"), (20,"bb"), (30,"cc")]

from the associative array:
[1:'a', 2:'b', 3:'c']

If possible reading things lazily from the associative array.



Idiomatic Python2 solution (iteritems is lazy):

 d = {1:'a', 2:'b', 3:'c'}
 [(k*10, v*2) for k,v in d.iteritems()]
[(10, 'aa'), (20, 'bb'), (30, 'cc')] D2 lazy solution without map(): import std.stdio, std.typecons; void main() { auto aa = [1:'a', 2:'b', 3:'c']; Tuple!(int, string)[] r; foreach (k, v; aa) r ~= tuple(k*10, ""~v~v); writeln(r); } The byPair() range allows to solve the task functionally ad lazily like this: import std.stdio, std.typecons, std.algorithm; void main() { auto aa = [1:'a', 2:'b', 3:'c']; auto r = map!q{ tuple(a[0]*10, a[1]~a[1]) }(aa.byPair()); writeln(r); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 20 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5466


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|AA ranges                   |Associative array byPair



After the work done for issue 4607 this is missing still:

import std.stdio, std.typecons, std.algorithm;
void main() {
    auto aa = [1:'a', 2:'b', 3:'c'];
    auto r = map!q{ tuple(a[0]*10, a[1]~a[1]) }(aa.byPair());
    writeln(r);
}


Also clarified the title of this issue.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 17 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5466




A comment by Andrei Alexandrescu:

 byPair is tricky because std.tuple is not visible from object.
-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 17 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5466




This example shows an use case of byItem. Given a string, the task here is to
show the char frequencies, putting higher frequencies on top, and sorting
alphabetically the chars that share the same frequency.

A Python 2.6 program that solves the problem:


from collections import defaultdict
text = "the d programming language is an object oriented " + \
       "imperative multi paradigm system programming " + \
       "language created by walter bright of digital mars"
frequences = defaultdict(int)
for c in text:
    frequences[c] += 1
pairs = sorted(frequences.iteritems(), key=lambda (c,f): (-f,c))
for (c, f) in pairs:
    print f, c



The output of the Python program:

20  
14 a
12 e
11 g
11 i
11 r
10 t
9 m
6 n
5 d
5 l
5 o
4 p
4 s
3 b
3 u
2 c
2 h
2 y
1 f
1 j
1 v
1 w



Three different solutions in D (probably there are other solutions, maybe even
better ones) using Phobos:


import std.stdio, std.typecons, std.algorithm, std.array;

void main() {
    auto text = "the d programming language is an object oriented " ~
                "imperative multi paradigm system programming " ~
                "language created by walter bright of digital mars";

    int[char] frequences;
    foreach (char c; text)
        frequences[c]++;

    Tuple!(int,char)[] pairs1 = array(map!(c => tuple(frequences[c],
c))(frequences.byKey));
    schwartzSort!(p => tuple(-p[0], p[1]))(pairs1);
    foreach (pair; pairs1)
        writeln(pair[0], " ", pair[1]);
    writeln();

    import std.conv;
    dchar[] keys = to!(dchar[])(frequences.keys);
    schwartzSort!(c => tuple(-frequences[cast(char)c], c))(keys);
    foreach (dchar c; keys)
        writeln(frequences[cast(char)c], " ", c);
    writeln();

    Tuple!(int,char)[] pairs1b = array(map!(c => tuple(-frequences[c],
c))(frequences.byKey));
    sort(pairs1b);
    foreach (pair; pairs1b)
        writeln(-pair[0], " ", pair[1]);
    writeln();
}



A version using AA.byPair (or AA.pairs) (I have not used 'auto' for type
clarity):

Tuple!(char,int)[] pairs2 = array(frequences.byPair);
schwartzSort!(c_f => tuple(-c_f[1], c_f[0]))(pairs2);
foreach (c_f; pairs2)
    writeln(c_f[1], " ", c_f[0]);


With the eager AA.pairs and tuple unpacking syntax too:

Tuple!(char,int)[] pairs3 = frequences.pairs;
schwartzSort!(tuple(c,f) => tuple(-f, c))(pairs3);
foreach ((c, f); pairs3)
    writeln(f, " ", c);


With AA.byPair, tuple unpacking syntax and schwartzSorted, this is approaching
the Python version:

Tuple!(char,int)[] pairs4 = schwartzSorted!(tuple(c,f) => tuple(-f,
c))(frequences.byPair);
foreach ((c, f); pairs4)
    writeln(f, " ", c);

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 29 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5466




See also Issue 8473

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 30 2012