Sorting based on associative arrays in D
Asked Answered
F

2

7

I am trying to follow examples given in various places for D apps. Generally when learning a language I start on example apps and change them myself, purely to test stuff out.

One app that caught my eye was to count the frequency of words in a block of text passed in. As the dictionary was built up in an associative array (with the elements storing the frequency, and the keys being the words themselves), the output was not in any particular order. So, I attempted to sort the array based on examples given on the site.

Anyway, the example showed a lambda 'sort!(...)(array);' but when I attempt the code dmd won't compile it.

Here's the boiled down code:

import std.stdio;
import std.string;

void main() {
   uint[string] freqs;

   freqs["the"] = 51;
   freqs["programming"] = 3;
   freqs["hello"] = 10;
   freqs["world"] = 10;

   /*...You get the point...*/

   //This is the actual example given, but it doesn't 
   //seem to work, old D version???
   //string[] words = array(freqs.keys);        

   //This seemed to work
   string[] words = freqs.keys;

   //Example given for how to sort the 'words' array based on 
   //external criteria (i.e. the frequency of the words from 
   //another array). This is the line where the compilor craps out!
   sort!((a,b) {return freqs[a] < freqs[b];})(words);

   //Should output in frequency order now!
   foreach(word; words) {
      writefln("%s -> %s", word, freqs[word]);
   }
}  

When I try to compile this code, I get the following

    s1.d(24): Error: undefined identifier sort
    s1.d(24): Error: function expected before (), not sort of type int

Can anyone tell me what I need to do here?

I use DMD v2.031, I've tried installing the gdc but this only seems to support the v1 language spec. I've only started looking at dil, so I can't comment on whether this supports the code above.

Freed answered 11/8, 2009 at 10:4 Comment(1)
GDC is kind of dead, the LLVM based LDC has taken it's place.Hendecahedron
W
11

Try adding this near the top of the file:

import std.algorithm;
Whereat answered 11/8, 2009 at 10:38 Comment(1)
Doh! Thanks, that works. It's always the simple stuff that's the hardest to find info on!Freed
R
2

Here's an even simpler way to get an input file (from cmdline), get lines/words and print a table of word frequencing, in descending order :

import std.algorithm;
import std.file;
import std.stdio;
import std.string;

void main(string[] args)
{   
    auto contents = cast(string)read(args[1]);
    uint[string] freqs;

    foreach(i,line; splitLines(contents))
        foreach(word; split(strip(line)))
            ++freqs[word];

    string[] words = freqs.keys;
    sort!((a,b)=> freqs[a]>freqs[b])(words);

    foreach(s;words) 
        writefln("%s\t\t%s",s,freqs[s]);
}

Well, almost 4 years later... :-)

Ridgley answered 6/2, 2013 at 13:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.