www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Key and value with ranges

reply Joel <joelcnz gmail.com> writes:
```d
import std;

auto data=“I went for a walk, and fell down a hole.”;

void main(string[] args) {
     int[string] dic;
     struct WordCnt {
         string word;
         ulong count;
         string toString() const {
             return text("Word: ", word, " - number of instances: 
", count);
         }
     }
     WordCnt[] wc;
     data
         .map!(c => lowercase.canFind(std.uni.toLower(c)) ? c : ' 
')
         .to!string
         .splitter
         .each!(d => dic[d]+=1);
     foreach(key, value; dic)
         wc~=WordCnt(key, value);
     wc.sort!"a.count>b.count".each!writeln;
}
```

How can I improve this code? Like avoiding using foreach.
Oct 01 2023
next sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:
 ```d
 import std;

 auto data=“I went for a walk, and fell down a hole.”;

 void main(string[] args) {
     int[string] dic;
     struct WordCnt {
         string word;
         ulong count;
         string toString() const {
             return text("Word: ", word, " - number of 
 instances: ", count);
         }
     }
     WordCnt[] wc;
     data
         .map!(c => lowercase.canFind(std.uni.toLower(c)) ? c : 
 ' ')
         .to!string
         .splitter
         .each!(d => dic[d]+=1);
     foreach(key, value; dic)
         wc~=WordCnt(key, value);
     wc.sort!"a.count>b.count".each!writeln;
 }
 ```

 How can I improve this code? Like avoiding using foreach.
You don't need a struct at all, you can just have an int[string] aa
Oct 01 2023
prev sibling next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:
 ```d
 import std;

 auto data=“I went for a walk, and fell down a hole.”;
You can improve it further by inlining ```d import std; auto data = "I went for a walk, and fell down a hole."; void main(string[] args) { int[string] dic; data.split(' ').each!(w => dic[w]++); sort(dic.keys).each!(w => writeln(dic[w], " ",w)); } ```
Oct 01 2023
parent reply Joel <joelcnz gmail.com> writes:
On Monday, 2 October 2023 at 06:19:29 UTC, Imperatorn wrote:
 On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:
 ```d
 import std;

 auto data=“I went for a walk, and fell down a hole.”;
You can improve it further by inlining ```d import std; auto data = "I went for a walk, and fell down a hole."; void main(string[] args) { int[string] dic; data.split(' ').each!(w => dic[w]++); sort(dic.keys).each!(w => writeln(dic[w], " ",w)); } ```
I want the output sorted by value.
Oct 02 2023
parent Salih Dincer <salihdb hotmail.com> writes:
On Monday, 2 October 2023 at 20:20:44 UTC, Joel wrote:
 I want the output sorted by value.
Look: https://forum.dlang.org/post/qjlmiohaoeolmoavwtif forum.dlang.org ```d struct SIRALA(T) { } ``` You can use SIRALA(T). Okay, his language is Turkish but our common language is D. His feature is that he uses double AA. You will like it. Here is the source: https://gist.github.com/run-dlang/808633909615dbda431baa01f795484f SDB 79
Oct 02 2023
prev sibling next sibling parent reply christian.koestlin <christian.koestlin gmail.com> writes:
On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:
 How can I improve this code? Like avoiding using foreach.
You could fold into a hash that counts the occurrences like that: ```d import std.uni : toLower; import std.array : split, array; import std.stdio : writeln; import std.algorithm : fold, sort, map; auto data="I went for a walk, and fell down a hole. a went"; int main(string[] args) { int[string] wc; data .toLower .split .fold!((result, element) { result[element] += 1; return result; })(wc) .byKeyValue .array .sort!((pair1, pair2) => pair1.value > pair2.value) .map!(pair => pair.key) .writeln ; return 0; } ``` Not sure how to get rid of the declaration of the empty wc hash though. Kind regards, Christian
Oct 02 2023
parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Monday, 2 October 2023 at 18:46:14 UTC, christian.koestlin 
wrote:
 On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:
 How can I improve this code? Like avoiding using foreach.
You could fold into a hash that counts the occurrences like that: ```d import std.uni : toLower; import std.array : split, array; import std.stdio : writeln; import std.algorithm : fold, sort, map; auto data="I went for a walk, and fell down a hole. a went"; int main(string[] args) { int[string] wc; data .toLower .split .fold!((result, element) { result[element] += 1; return result; })(wc) .byKeyValue .array .sort!((pair1, pair2) => pair1.value > pair2.value) .map!(pair => pair.key) .writeln ; return 0; } ``` Not sure how to get rid of the declaration of the empty wc hash though. Kind regards, Christian
Slightly improved: ```d import std; auto data="I went for a walk, and fell down a hole. a went"; int main(string[] args) { data .toLower .split .fold!((ref result, element) { ++result[element]; return result; })(uint[string].init) .byKeyValue .array .sort!((pair1, pair2) => pair1.value > pair2.value) .each!(pair => writeln("Word: ", pair.key, " - number of instances: ", pair.value)) ; return 0; } ``` Output: ``` Word: a - number of instances: 3 Word: went - number of instances: 2 Word: and - number of instances: 1 Word: i - number of instances: 1 Word: hole. - number of instances: 1 Word: for - number of instances: 1 Word: down - number of instances: 1 Word: fell - number of instances: 1 Word: walk, - number of instances: 1 ```
Oct 02 2023
parent reply christian.koestlin <christian.koestlin gmail.com> writes:
On Tuesday, 3 October 2023 at 01:55:43 UTC, Andrey Zherikov wrote:
 On Monday, 2 October 2023 at 18:46:14 UTC, christian.koestlin 
 wrote:
 [...]
Slightly improved: ```d import std; [...]
Thanks .. the thing with ref result is very clever! Should `ref result` be `return result`? Kind regards, Christian
Oct 03 2023
parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Tuesday, 3 October 2023 at 19:57:06 UTC, christian.koestlin 
wrote:
 On Tuesday, 3 October 2023 at 01:55:43 UTC, Andrey Zherikov 
 wrote:
 On Monday, 2 October 2023 at 18:46:14 UTC, christian.koestlin 
 wrote:
 [...]
Slightly improved: ```d import std; [...]
Thanks .. the thing with ref result is very clever! Should `ref result` be `return result`?
`ref` might not be necessary fo AA but I'm not sure. `fold` requires function to return something (see [doc](https://dlang.org/phobos/std_algorithm_iteration.html#fold)):
 for each element x in range, result = fun(result, x) gets 
 evaluated.
Oct 03 2023
parent christian.koestlin <christian.koestlin gmail.com> writes:
On Tuesday, 3 October 2023 at 20:22:30 UTC, Andrey Zherikov wrote:
 On Tuesday, 3 October 2023 at 19:57:06 UTC, christian.koestlin 
 wrote:
 On Tuesday, 3 October 2023 at 01:55:43 UTC, Andrey Zherikov 
 wrote:
 On Monday, 2 October 2023 at 18:46:14 UTC, christian.koestlin 
 wrote:
 [...]
Slightly improved: ```d import std; [...]
Thanks .. the thing with ref result is very clever! Should `ref result` be `return result`?
`ref` might not be necessary fo AA but I'm not sure.
I found this in regards to AAs: https://forum.dlang.org/post/baewchcnyfibkvuiyybj forum.dlang.org So it might be more efficient in this case to pass the AA as reference.
 `fold` requires function to return something (see 
 [doc](https://dlang.org/phobos/std_algorithm_iteration.html#fold)):
 for each element x in range, result = fun(result, x) gets 
 evaluated.
It's clear that the function needs to return something, but I was thinking if it would make sense to "document" how one works with the accumulator by indicating it as `return` instead of `ref`. I just tried to read through: https://dlang.org/spec/function.html#param-storage, but there is more to it .. like `return ref`, `return ref scope`, and what not .. so I am not so sure anymore.
Oct 03 2023
prev sibling next sibling parent Joel <joelcnz gmail.com> writes:
On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:
 ```d
 import std;

 auto data=“I went for a walk, and fell down a hole.”;

 void main(string[] args) {
     int[string] dic;
     struct WordCnt {
         string word;
         ulong count;
         string toString() const {
             return text("Word: ", word, " - number of 
 instances: ", count);
         }
     }
     WordCnt[] wc;
     data
         .map!(c => lowercase.canFind(std.uni.toLower(c)) ? c : 
 ' ')
         .to!string
         .splitter
         .each!(d => dic[d]+=1);
     foreach(key, value; dic)
         wc~=WordCnt(key, value);
     wc.sort!"a.count>b.count".each!writeln;
 }
 ```

 How can I improve this code? Like avoiding using foreach.
This is what I've got so far. Is there a way to do it any better? ```d import std; auto data="I went for a walk, and fell down a hole."; void main() { int[string] aa; struct WordCnt { string word; ulong count; string toString() const { return text("Word: ", word, " - number of instances: ", count); } } WordCnt[] wc; data .map!(c => lowercase.canFind(std.uni.toLower(c)) ? c : ' ') .to!string .splitter .each!(d => aa[d]+=1); aa.each!((key, value) { wc~=WordCnt(key, value); }); wc.sort!"a.count>b.count" .each!writeln; } ```
Oct 02 2023
prev sibling parent Joel <joelcnz gmail.com> writes:
On Monday, 2 October 2023 at 02:47:37 UTC, Joel wrote:
 ```d
 import std;

 auto data=“I went for a walk, and fell down a hole.”;
 ```
[snip]
 How can I improve this code? Like avoiding using foreach.
This works for me: ```d import std; auto data="I went for a walk, and fell down a hole."; void main(string[] args) { if (args.length>1 && args[1].exists) data=readText(args[1]); data .toLower .map!(c => lowercase.canFind(std.uni.toLower(c)) ? c : ' ') .to!string .split .fold!((ref result, element) { result[element]+=1; return result; })(uint[string].init) .byKeyValue .array .sort!"a.value>b.value" .each!(pair => writeln("Word: ", pair.key, " - number of instances: ", pair.value)); } ```
Oct 02 2023