www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - reading file byLine

reply "Namal" <sotis22 mail.ru> writes:
Hello,

I want to read a file line by line and store each line in a 
string. I found this example with byLine and ranges. First of 
all, do I need the range lib at all to do this and if so what is 
the range of the end of the file?
Sep 02 2015
parent reply "cym13" <cpicard openmailbox.org> writes:
On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote:
 Hello,

 I want to read a file line by line and store each line in a 
 string. I found this example with byLine and ranges. First of 
 all, do I need the range lib at all to do this and if so what 
 is the range of the end of the file?
You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations.
Sep 02 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Wednesday, 2 September 2015 at 13:12:39 UTC, cym13 wrote:
 On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote:
 Hello,

 I want to read a file line by line and store each line in a 
 string. I found this example with byLine and ranges. First of 
 all, do I need the range lib at all to do this and if so what 
 is the range of the end of the file?
You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations.
Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. I also tried to append a line to an array of strings but it failed because the line is a char?
Sep 02 2015
next sibling parent "qznc" <qznc web.de> writes:
On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote:
 On Wednesday, 2 September 2015 at 13:12:39 UTC, cym13 wrote:
 On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote:
 Hello,

 I want to read a file line by line and store each line in a 
 string. I found this example with byLine and ranges. First of 
 all, do I need the range lib at all to do this and if so what 
 is the range of the end of the file?
You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations.
Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it.
Just like in C++: buffer = line; However, you can just use "line" instead of "buffer" then. The byLine does buffer internally, so it overwrites "line" on the next iteration of foreach. If you want to keep the line string, then make a copy "line.idup".
 I also tried to append a line to an array of strings but it 
 failed because the line is a char?
Here is how to get an array of lines: import std.stdio; void main() { auto f = File("myfile"); string buffer[]; foreach (line ; f.byLine) { buffer ~= line.idup; } f.close(); writeln(buffer); }
Sep 02 2015
prev sibling parent reply "cym13" <cpicard openmailbox.org> writes:
On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote:
 Thx, cym. I have a question about a D strings though. In c++ I 
 would just reuse the string buffer with the "=" how can I clear 
 the string after i store a line in the buffer and do something 
 with it. I also tried to append a line to an array of strings 
 but it failed because the line is a char?
In D you can do as in C++: buffer = ""; // or a brand new string You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using: buffer.init(); When reading files the default type you get is dchar[]. There are different kind of strings in D, you way want to check http://dlang.org/arrays.html#strings . If you want to append to an array of strings, simply convert your line to type string: import std.conv; import std.stdio; void main() { string[] buffer; foreach (line ; File("test.txt").byLine) buffer ~= line.to!string; // <- Here is the magic writeln(buffer); }
Sep 02 2015
next sibling parent "cym13" <cpicard openmailbox.org> writes:
On Wednesday, 2 September 2015 at 15:04:10 UTC, cym13 wrote:
 On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote:
 Thx, cym. I have a question about a D strings though. In c++ I 
 would just reuse the string buffer with the "=" how can I 
 clear the string after i store a line in the buffer and do 
 something with it. I also tried to append a line to an array 
 of strings but it failed because the line is a char?
In D you can do as in C++: buffer = ""; // or a brand new string You can also reset a variable to its initial state (what you would hav had if you hadn't initialized it) using: buffer.init(); When reading files the default type you get is dchar[]. There are different kind of strings in D, you way want to check http://dlang.org/arrays.html#strings . If you want to append to an array of strings, simply convert your line to type string: import std.conv; import std.stdio; void main() { string[] buffer; foreach (line ; File("test.txt").byLine) buffer ~= line.to!string; // <- Here is the magic writeln(buffer); }
Actually, even if converting works, what qznc did is better in the case of file reading. And even better would be to use .byLineCopy which basically does the same thing as qznc's solution but more efficiently: import std.stdio; void main() { string[] buffer; foreach (line ; File("test.txt").byLineCopy) buffer ~= line; writeln(buffer); }
Sep 02 2015
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Wednesday, 2 September 2015 at 15:04:10 UTC, cym13 wrote:
 You can also reset a variable to its initial state (what you 
 would hav had if you hadn't initialized it) using:

 buffer.init();
Huh? That doesn't work... Instead, use: buffer = buffer.init;
Sep 02 2015
parent reply "Namal" <sotis22 mail.ru> writes:
Thx guys, this helped alot. The next thing I want to do is read 
the file line by line and split the stream into words. I found 
this example of code that seems to do sort of something like it. 
How can I modyfy it so I can store the words in an array of 
strings? Is a => a.length the iterator range?


import std.algorithm, std.stdio, std.string;
// Count words in a file using ranges.
void main()
{
     auto file = File("file.txt"); // Open for reading
     const wordCount = file.byLine()            // Read lines
                           .map!split           // Split into words
                           .map!(a => a.length) // Count words per 
line
                           .sum();              // Total word count
     writeln(wordCount);
}
Sep 02 2015
parent reply "wobbles" <grogan.colin gmail.com> writes:
On Wednesday, 2 September 2015 at 21:53:20 UTC, Namal wrote:
 Thx guys, this helped alot. The next thing I want to do is read 
 the file line by line and split the stream into words. I found 
 this example of code that seems to do sort of something like 
 it. How can I modyfy it so I can store the words in an array of 
 strings? Is a => a.length the iterator range?


 import std.algorithm, std.stdio, std.string;
 // Count words in a file using ranges.
 void main()
 {
     auto file = File("file.txt"); // Open for reading
     const wordCount = file.byLine()            // Read lines
                           .map!split           // Split into 
 words
                           .map!(a => a.length) // Count words 
 per line
                           .sum();              // Total word 
 count
     writeln(wordCount);
 }
I would do what you want like this auto file = File("file.txt"); auto words = file.byLine() // you've all lines in range .map!(a => a.split); // read each line, splitting it into words // now you've a range, where each element is an array of words The map!(a => a.split) line simply maps each element to the return value of a.split - this is the predicate. The a => a.split syntax is a lambda expression that tells map what to do on each element.
Sep 02 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Wednesday, 2 September 2015 at 22:19:11 UTC, wobbles wrote:
 On Wednesday, 2 September 2015 at 21:53:20 UTC, Namal wrote:
 Thx guys, this helped alot. The next thing I want to do is 
 read the file line by line and split the stream into words. I 
 found this example of code that seems to do sort of something 
 like it. How can I modyfy it so I can store the words in an 
 array of strings? Is a => a.length the iterator range?


 import std.algorithm, std.stdio, std.string;
 // Count words in a file using ranges.
 void main()
 {
     auto file = File("file.txt"); // Open for reading
     const wordCount = file.byLine()            // Read lines
                           .map!split           // Split into 
 words
                           .map!(a => a.length) // Count words 
 per line
                           .sum();              // Total word 
 count
     writeln(wordCount);
 }
I would do what you want like this auto file = File("file.txt"); auto words = file.byLine() // you've all lines in range .map!(a => a.split); // read each line, splitting it into words // now you've a range, where each element is an array of words The map!(a => a.split) line simply maps each element to the return value of a.split - this is the predicate. The a => a.split syntax is a lambda expression that tells map what to do on each element.
hello, just copy pasting this brought me those errors: ep18.d(10): Error: no property 'split' for type 'char[]' /usr/include/dmd/phobos/std/algorithm.d(427): instantiated from here: MapResult!(__lambda1, ByLine!(char, char)) ep18.d(10): instantiated from here: map!(ByLine!(char, char)) and then a long list to the end of my code Error: undefined identifier a
Sep 03 2015
parent reply "Namal" <sotis22 mail.ru> writes:
 ep18.d(10): Error: no property 'split' for type 'char[]'
 /usr/include/dmd/phobos/std/algorithm.d(427):        
 instantiated from here: MapResult!(__lambda1, ByLine!(char, 
 char))
 ep18.d(10):        instantiated from here: map!(ByLine!(char, 
 char))

 and then a long list to the end of my code
  Error: undefined identifier a
Hmm, seems I forgot to add std.string, now it works, but words seems not to be an array, at least I cannot access it like an array. words[0][0] leads to Error: no [] operator overload for type MapResult!(__lambda1, ByLine!(char, char)) So is is a map? How can I convert all the elements in it to integer and store it in a real array?
Sep 03 2015
parent reply "Jordan Wilson" <wilsonjord gmail.com> writes:
On Thursday, 3 September 2015 at 22:21:57 UTC, Namal wrote:
 ep18.d(10): Error: no property 'split' for type 'char[]'
 /usr/include/dmd/phobos/std/algorithm.d(427):        
 instantiated from here: MapResult!(__lambda1, ByLine!(char, 
 char))
 ep18.d(10):        instantiated from here: map!(ByLine!(char, 
 char))

 and then a long list to the end of my code
  Error: undefined identifier a
Hmm, seems I forgot to add std.string, now it works, but words seems not to be an array, at least I cannot access it like an array. words[0][0] leads to Error: no [] operator overload for type MapResult!(__lambda1, ByLine!(char, char)) So is is a map? How can I convert all the elements in it to integer and store it in a real array?
I believe it's by using array: auto words = file.byLine() // you've all lines in range .map!(a => a.split).array();
Sep 03 2015
parent reply "Jordan Wilson" <wilsonjord gmail.com> writes:
On Thursday, 3 September 2015 at 22:48:01 UTC, Jordan Wilson 
wrote:
 On Thursday, 3 September 2015 at 22:21:57 UTC, Namal wrote:
 ep18.d(10): Error: no property 'split' for type 'char[]'
 /usr/include/dmd/phobos/std/algorithm.d(427):        
 instantiated from here: MapResult!(__lambda1, ByLine!(char, 
 char))
 ep18.d(10):        instantiated from here: map!(ByLine!(char, 
 char))

 and then a long list to the end of my code
  Error: undefined identifier a
Hmm, seems I forgot to add std.string, now it works, but words seems not to be an array, at least I cannot access it like an array. words[0][0] leads to Error: no [] operator overload for type MapResult!(__lambda1, ByLine!(char, char)) So is is a map? How can I convert all the elements in it to integer and store it in a real array?
I believe it's by using array: auto words = file.byLine() // you've all lines in range .map!(a => a.split).array();
Sorry, I didn't notice the "convert all the elements in it to integer" part. I think I saw reference to the to! before...that is one way to convert. auto words = file.byLine() // you've all lines in range .map!(a => a.split) .map!(a => to!int(a)).array();
Sep 03 2015
next sibling parent reply "Namal" <sotis22 mail.ru> writes:
 Sorry, I didn't notice the "convert all the elements in it to 
 integer" part.
 I think I saw reference to the to! before...that is one way to 
 convert.

 auto words = file.byLine()           // you've all lines in 
 range
                    .map!(a => a.split)
 		   .map!(a => to!int(a)).array();
import std.file, std.stdio, std.string, std.conv; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => to!int(a)).array(); writeln(numbers); } ep18.d(7): Error: no property 'map' for type 'ByLine!(char, char)'
Sep 03 2015
parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Sep 03, 2015 at 11:22:09PM +0000, Namal via Digitalmars-d-learn wrote:
Sorry, I didn't notice the "convert all the elements in it to integer"
part.
I think I saw reference to the to! before...that is one way to convert.

auto words = file.byLine()           // you've all lines in range
                   .map!(a => a.split)
		   .map!(a => to!int(a)).array();
import std.file, std.stdio, std.string, std.conv; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => to!int(a)).array(); writeln(numbers); } ep18.d(7): Error: no property 'map' for type 'ByLine!(char, char)'
import std.algorithm : map; T -- Never step over a puddle, always step around it. Chances are that whatever made it is still dripping.
Sep 03 2015
prev sibling parent reply "Jordan Wilson" <wilsonjord gmail.com> writes:
Actually, need an extra map I think:

auto word = file.byLine()
                     .map!(a => a.split)
                     .map!(a => map!(a => to!int(a))(a))
                     .array();
Sep 03 2015
parent reply "Jordan Wilson" <wilsonjord gmail.com> writes:
And also:
import std.algorithm

Sorry, I should have taken the time to answer properly and fully.
Sep 03 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson 
wrote:
 And also:
 import std.algorithm

 Sorry, I should have taken the time to answer properly and 
 fully.
import std.file, std.stdio, std.string, std.conv, std.algorithm; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array(); writeln(numbers); } Error: no property 'array' for type 'MapResult!(__lambda2, MapResult!(__lambda1, ByLine!(char, char)))' Still an error.
Sep 03 2015
next sibling parent reply "Jordan Wilson" <wilsonjord gmail.com> writes:
On Thursday, 3 September 2015 at 23:28:37 UTC, Namal wrote:
 On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson 
 wrote:
 And also:
 import std.algorithm

 Sorry, I should have taken the time to answer properly and 
 fully.
import std.file, std.stdio, std.string, std.conv, std.algorithm; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array(); writeln(numbers); } Error: no property 'array' for type 'MapResult!(__lambda2, MapResult!(__lambda1, ByLine!(char, char)))' Still an error.
import std.array
Sep 03 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Thursday, 3 September 2015 at 23:31:27 UTC, Jordan Wilson 
wrote:
 On Thursday, 3 September 2015 at 23:28:37 UTC, Namal wrote:
 On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson 
 wrote:
 And also:
 import std.algorithm

 Sorry, I should have taken the time to answer properly and 
 fully.
import std.file, std.stdio, std.string, std.conv, std.algorithm; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array(); writeln(numbers); } Error: no property 'array' for type 'MapResult!(__lambda2, MapResult!(__lambda1, ByLine!(char, char)))' Still an error.
import std.array
Thx, finaly, this is so much harder to understand than c++ iostream
Sep 03 2015
parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Sep 03, 2015 at 11:38:54PM +0000, Namal via Digitalmars-d-learn wrote:
 On Thursday, 3 September 2015 at 23:31:27 UTC, Jordan Wilson wrote:
On Thursday, 3 September 2015 at 23:28:37 UTC, Namal wrote:
On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson wrote:
And also:
import std.algorithm

Sorry, I should have taken the time to answer properly and fully.
import std.file, std.stdio, std.string, std.conv, std.algorithm; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array(); writeln(numbers); } Error: no property 'array' for type 'MapResult!(__lambda2, MapResult!(__lambda1, ByLine!(char, char)))' Still an error.
import std.array
Thx, finaly, this is so much harder to understand than c++ iostream
I would have written it slightly differently, to emphasize what exactly is going on: auto numbers = File("text.txt") // read file .byLine() // line by line .map!(a => a.split // split each line into words .map!(a => to!int(a)) // convert each word into int .array) // collect the ints into an array (per line) .array; // collect all line arrays into one big array This is the functional way of doing it, of course. If you're more comfortable with the C++-style imperative approach, you could do this instead: auto file = File("text.txt"); int[][] numbers; foreach (line; file.byLine) { auto words = line.split; int[] lineNums; foreach (word; words) { lineNums ~= word.to!int; } numbers ~= lineNums; } The functional approach is admittedly a bit harder to understand at first, but it's extremely powerful because it processes everything in a pipeline, and you can compose operators on the pipeline easily, rearrange the sequence of operations, etc.. In the imperative nested-loop approach, things quickly get out of hand once the loop is nested about 2-3 levels deep. A nested loop of 6-7 levels deep would be basically impossible to understand, maintain, or debug without major refactoring into smaller functions. (In fact, split() is a library-provided function that basically encapsulates one of those nested loops.) But if you take the refactoring to its logical conclusion, you'll eventually end up with a whole bunch of tiny functions with only a single loop each, each calling the next function in a chain -- in other words, you arrive at the functional pipeline approach. :-) D allows you to do it either way, but the superior approach IMO is to learn the functional pipeline approach. T -- Life is too short to run proprietary software. -- Bdale Garbee
Sep 03 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Thursday, 3 September 2015 at 23:54:44 UTC, H. S. Teoh wrote:
 On Thu, Sep 03, 2015 at 11:38:54PM +0000, Namal via 
 Digitalmars-d-learn wrote:
 On Thursday, 3 September 2015 at 23:31:27 UTC, Jordan Wilson 
 wrote:
On Thursday, 3 September 2015 at 23:28:37 UTC, Namal wrote:
On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson 
wrote:
And also:
import std.algorithm

Sorry, I should have taken the time to answer properly and 
fully.
import std.file, std.stdio, std.string, std.conv, std.algorithm; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array(); writeln(numbers); } Error: no property 'array' for type 'MapResult!(__lambda2, MapResult!(__lambda1, ByLine!(char, char)))' Still an error.
import std.array
Thx, finaly, this is so much harder to understand than c++ iostream
I would have written it slightly differently, to emphasize what exactly is going on: auto numbers = File("text.txt") // read file .byLine() // line by line .map!(a => a.split // split each line into words .map!(a => to!int(a)) // convert each word into int .array) // collect the ints into an array (per line) .array; // collect all line arrays into one big array This is the functional way of doing it, of course. If you're more comfortable with the C++-style imperative approach, you could do this instead: auto file = File("text.txt"); int[][] numbers; foreach (line; file.byLine) { auto words = line.split; int[] lineNums; foreach (word; words) { lineNums ~= word.to!int; } numbers ~= lineNums; } The functional approach is admittedly a bit harder to understand at first, but it's extremely powerful because it processes everything in a pipeline, and you can compose operators on the pipeline easily, rearrange the sequence of operations, etc.. In the imperative nested-loop approach, things quickly get out of hand once the loop is nested about 2-3 levels deep. A nested loop of 6-7 levels deep would be basically impossible to understand, maintain, or debug without major refactoring into smaller functions. (In fact, split() is a library-provided function that basically encapsulates one of those nested loops.) But if you take the refactoring to its logical conclusion, you'll eventually end up with a whole bunch of tiny functions with only a single loop each, each calling the next function in a chain -- in other words, you arrive at the functional pipeline approach. :-) D allows you to do it either way, but the superior approach IMO is to learn the functional pipeline approach. T
Thx Theo, this and the lack of foolproof tutorials were the reason why I gave up on D 2 years ago and went instead to C++. But I am not giving up this time. That being said, when do I have to import std.array and std.string? Every time I use std.array? I can obviously use arrays and strings without those libs.
Sep 03 2015
next sibling parent "Jordan Wilson" <wilsonjord gmail.com> writes:
On Friday, 4 September 2015 at 00:18:15 UTC, Namal wrote:
 On Thursday, 3 September 2015 at 23:54:44 UTC, H. S. Teoh wrote:
 [...]
Thx Theo, this and the lack of foolproof tutorials were the reason why I gave up on D 2 years ago and went instead to C++. But I am not giving up this time. That being said, when do I have to import std.array and std.string? Every time I use std.array? I can obviously use arrays and strings without those libs.
My 2 cents, as someone who is newish to D, I'd also recommend the above approach. I found the whole ranges thing to be hard to get at first, but I do find myself using ranges + std.algorithm more and more (even though it's mostly just basic map and filter).
Sep 03 2015
prev sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Sep 04, 2015 at 12:18:14AM +0000, Namal via Digitalmars-d-learn wrote:
[...]
 That being said, when do I have to import std.array and std.string?
 Every time I use std.array? I can obviously use arrays and strings
 without those libs.
Arrays and strings are built into the language; but many common operations on arrays and strings are not built-in, but are provided in the standard library, i.e., std.array and std.string. So if you use just the plain ~, ~=, operators, then you don't need std.array or std.string. But if you need functions like split() or array(), then you need to import std.array. If you're only dealing with strings as char arrays, then that's all you need. But if you want some string-specific functions, e.g., isNumeric(), chomp(), capitalize(), etc., then you need std.string. Also, some of the more generic operations that can be applied to more than just arrays or strings, will be found in std.algorithm, such as map(), find(), count(), startsWith(), etc.. Basically, if an operation *only* applies to strings, it should generally be found in std.string; if it can also apply to arrays, then it should be found in std.array. If it can be applied to more than just arrays (that is, ranges, e.g., a file stream, a network socket, a sequence of values produced by a generating function, etc., anything with array-like sequential semantics that are not necessarily actual arrays), then it will generally be found in std.algorithm. One useful rule-of-thumb to decide where to look is to ask yourself if an operation on an array can also be logically applied to a linked-list. If it can, it's probably in std.algorithm. If not (i.e. it depends on semantics specific to arrays), then it's probably in std.array. Hope this helps. T -- Latin's a dead language, as dead as can be; it killed off all the Romans, and now it's killing me! -- Schoolboy
Sep 03 2015
parent reply "Namal" <sotis22 mail.ru> writes:
 Hope this helps.
Yes, it does. I have a question about arrays. I can sort an array A by sort(A); How can I get just the maximum element? Do I need to give a range for it?
Sep 03 2015
parent reply "deed" <none none.none> writes:
On Friday, 4 September 2015 at 01:31:28 UTC, Namal wrote:
 How can I get just the maximum element? Do I need to give a 
 range for it?
Use max? http://dlang.org/phobos/std_algorithm_comparison.html#max
Sep 03 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Friday, 4 September 2015 at 01:55:13 UTC, deed wrote:
 On Friday, 4 September 2015 at 01:31:28 UTC, Namal wrote:
 How can I get just the maximum element? Do I need to give a 
 range for it?
Use max? http://dlang.org/phobos/std_algorithm_comparison.html#max
Sorry, I don't understand the syntax yet. How do I tell max to search all elements? I mean, why does sort(myarray) is legit and max(myarray) isn't.
Sep 04 2015
parent reply "deed" <none none.none> writes:
On Friday, 4 September 2015 at 07:27:54 UTC, Namal wrote:
 On Friday, 4 September 2015 at 01:55:13 UTC, deed wrote:
 On Friday, 4 September 2015 at 01:31:28 UTC, Namal wrote:
 How can I get just the maximum element? Do I need to give a 
 range for it?
Use max? http://dlang.org/phobos/std_algorithm_comparison.html#max
Sorry, I don't understand the syntax yet. How do I tell max to search all elements?
You can search all elements by using reduce http://dlang.org/phobos/std_algorithm_iteration.html#reduce
 I mean, why does sort(myarray) is legit and max(myarray) isn't.
I don't know why, other than that is the current design in Phobos. import std.algorithm, std.range, std.array, std.string, std.stdio, std.conv; int[] arr1 = [1, 2, 30]; //arr1.max.writeln; // Doesn't work, as you say arr1.reduce!max.writeln; // This does. Prints 30. int[] arr2 = [4, 5, 6]; int[][] arr = [arr1, arr2]; arr.reduce!max.writeln; // Returns either arr1 or arr2. Element by // element comparison until one is greatest. // Prints arr2, since 1 < 4. arr.joiner.reduce!max.writeln; // Flattens arr1 and arr2 to one arr and // finds max. Prints 30. //For your example: auto f = File("filename", "r"); auto numbers = f // 1 2 3\n4 5 6 .byLine // ["1 2 3", "4 5 6"] .map!(a => a.split) // [["1", "2", "3"], ["4", "5", "6"]] .map!(a => a.to!(int[]))// [[1, 2, 3], [4, 5, 6]] .array; // Allocates and puts the elements into an // int[][] for reuse of state. numbers // [[1, 2, 3], [4, 5, 6]] .map!(reduce!max) // [3, 6] .writeln; // prints [3, 6] numbers // [[1, 2, 3], [4, 5, 6]] .joiner // [1, 2, 3, 4, 5, 6] .reduce!max // 6 .writeln; // prints 6
Sep 04 2015
parent reply "Edwin van Leeuwen" <edder tkwsping.nl> writes:
On Friday, 4 September 2015 at 11:50:23 UTC, deed wrote:
 import std.algorithm, std.range, std.array, std.string, 
 std.stdio,
 std.conv;

 int[] arr1 = [1, 2, 30];
 //arr1.max.writeln;         // Doesn't work, as you say
 arr1.reduce!max.writeln;    // This does. Prints 30.
Again using reduce is the functional way to do it. The above basically boils down to: int[] arr1 = [1, 2, 30]; int maxElement = arr1[1]; foreach( element; arr1[2..$] ) //2..$ is short hand for second till last ($) element { maxElement = max( maxElement, element ); } writeln( maxElement );
Sep 04 2015
parent reply "Edwin van Leeuwen" <edder tkwsping.nl> writes:
On Friday, 4 September 2015 at 12:06:08 UTC, Edwin van Leeuwen 
wrote:
 On Friday, 4 September 2015 at 11:50:23 UTC, deed wrote:
 import std.algorithm, std.range, std.array, std.string, 
 std.stdio,
 std.conv;

 int[] arr1 = [1, 2, 30];
 //arr1.max.writeln;         // Doesn't work, as you say
 arr1.reduce!max.writeln;    // This does. Prints 30.
Again using reduce is the functional way to do it. The above basically boils down to: int[] arr1 = [1, 2, 30]; int maxElement = arr1[1]; foreach( element; arr1[2..$] ) //2..$ is short hand for second till last ($) element { maxElement = max( maxElement, element ); } writeln( maxElement );
Sorry been using too much R, so my indexes are off by 1: int[] arr1 = [1, 2, 30]; int maxElement = arr1[0]; foreach( element; arr1[1..$] ) //1..$ is short hand for second till last ($) element { maxElement = max( maxElement, element ); } writeln( maxElement );
Sep 04 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Friday, 4 September 2015 at 12:09:19 UTC, Edwin van Leeuwen 
wrote:
 On Friday, 4 September 2015 at 12:06:08 UTC, Edwin van Leeuwen 
 wrote:
 On Friday, 4 September 2015 at 11:50:23 UTC, deed wrote:
 import std.algorithm, std.range, std.array, std.string, 
 std.stdio,
 std.conv;

 int[] arr1 = [1, 2, 30];
 //arr1.max.writeln;         // Doesn't work, as you say
 arr1.reduce!max.writeln;    // This does. Prints 30.
Again using reduce is the functional way to do it. The above basically boils down to: int[] arr1 = [1, 2, 30]; int maxElement = arr1[1]; foreach( element; arr1[2..$] ) //2..$ is short hand for second till last ($) element { maxElement = max( maxElement, element ); } writeln( maxElement );
Sorry been using too much R, so my indexes are off by 1: int[] arr1 = [1, 2, 30]; int maxElement = arr1[0]; foreach( element; arr1[1..$] ) //1..$ is short hand for second till last ($) element { maxElement = max( maxElement, element ); } writeln( maxElement );
Thx guys. Now I try out the split function. I read the file as a single string? auto arr = split(cast(string)read(filename),","); where the file has "A", "B", "C" and I get the output ["\"A\"", " \"B\"", " \"C\"\n"] I can understand that read functions reads the endl but what does it with the quotation marks? how can I modify read so I get just ["A", "B", "C"]
Sep 05 2015
parent reply "deed" <none none.none> writes:
On Saturday, 5 September 2015 at 12:41:37 UTC, Namal wrote:
 Thx guys. Now I try out the split function. I read the file as 
 a single string?

 auto arr = split(cast(string)read(filename),",");

 where the file has "A", "B", "C"

 and I get the output ["\"A\"", " \"B\"", " \"C\"\n"]

 I can understand that read functions reads the endl but what 
 does it with the quotation marks? how can I modify read so I 
 get just ["A", "B", "C"]
'\' is the escape character and is used to disambiguate start or end of string (") and a quotation mark within the string (\"), the same way as "\n" means newline and not '\' 'n', which would have been "\\n". So what you have is [`"A"`, ` "B"`, ` "C"\n`], if you use ` for start\stop of string. You say you want ["A", "B", "C"], so you need to remove whitespace. You can do that with std.string.strip. Assuming you also want to remove the quotation marks present in the file, one solution is to use std.string.chomp and std.string.chompPrefix, for example: string s = cast(string) read(filename); s.split(",") .map!strip .map!(s => chomp(s, "\"") .map!(s => chompPrefix(s, "\"") .writeln ;
Sep 05 2015
parent reply "deed" <none none.none> writes:
On Saturday, 5 September 2015 at 14:44:19 UTC, deed wrote:
  .map!(s => chomp(s, "\"")
  .map!(s => chompPrefix(s, "\"")
should be .map!(s => chomp(s, "\"")) .map!(s => chompPrefix(s, "\""))
Sep 05 2015
next sibling parent reply "Namal" <sotis22 mail.ru> writes:
On Saturday, 5 September 2015 at 14:49:13 UTC, deed wrote:
 On Saturday, 5 September 2015 at 14:44:19 UTC, deed wrote:
  .map!(s => chomp(s, "\"")
  .map!(s => chompPrefix(s, "\"")
should be .map!(s => chomp(s, "\"")) .map!(s => chompPrefix(s, "\""))
Yeah, I have have been trying this example from wiki books https://en.wikibooks.org/wiki/Learning_D_With_Project_Euler It is not even compiling.
Sep 05 2015
parent reply "deed" <none none.none> writes:
On Saturday, 5 September 2015 at 17:31:39 UTC, Namal wrote:
 Yeah, I have have been trying this example from wiki books

 https://en.wikibooks.org/wiki/Learning_D_With_Project_Euler

 It is not even compiling.
What exactly is not compiling?
Sep 05 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Saturday, 5 September 2015 at 18:57:52 UTC, deed wrote:
 On Saturday, 5 September 2015 at 17:31:39 UTC, Namal wrote:
 Yeah, I have have been trying this example from wiki books

 https://en.wikibooks.org/wiki/Learning_D_With_Project_Euler

 It is not even compiling.
What exactly is not compiling?
the last codesample on the bottom. I think because of the old D? Index for the last array.length-1 is now $-1. But also I get Error: undefined identifier 'file' for the read line. But even when I fixed those errors the strings I got were with those quotation marks and backslashes. However, with your help I could solve it now. I moved to the next problem and wrote the program for it import std.stdio, std.algorithm, std.array; bool abundant(int n){ int[] a; foreach(i;1..n) if(!(n%i)) a~=i; auto sum = reduce!((a,b)=>a+b)(0,a); return sum>n; } void main(){ long sum; int[] arr; int[28123] mark; foreach(i;1..28124) if(abundant(i)) arr~=i; foreach(i;arr) foreach(j;arr){ if(i+j>28123) break; mark[i+j-1] = 1; } for(auto i = 0;i<mark.length;++i) if(!mark[i]) sum+=i+1; writeln(sum); } How can I generate the array arr the functional way with reduce and the function abundant as filter. Tried it on my own but failed. Also, if I use reduce on an array, like I did for the sum, what does the zero mean in the range?
Sep 05 2015
parent reply anonymous <anonymous example.com> writes:
On Saturday 05 September 2015 22:22, Namal wrote:

 import std.stdio, std.algorithm, std.array;
 
 bool abundant(int n){
[...]
 }
 
 
 
 void main(){
 	
 	long sum;
 	int[] arr;
 	int[28123] mark;
 	
 	foreach(i;1..28124)
 		if(abundant(i))
 			arr~=i;
[...]
 }
 
 How can I generate the array arr the functional way with reduce 
 and the function abundant as filter. Tried it on my own but 
 failed.
import std.range: iota; int[] arr = iota(1, 28124).filter!abundant.array;
 Also, if I use reduce on an array, like I did for the 
 sum, what does the zero mean in the range?
You mean the 0 in this: `reduce!((a,b)=>a+b)(0,a)`, right? It's used as the initial value for the `a` argument to the lambda. That is, the first calculation there is 0+a[0]. Then a[1] is added to that, and so on. Note that there's a specialized `std.algorithm.iteration.sum`.
Sep 05 2015
parent reply "Namal" <sotis22 mail.ru> writes:
 Note that there's a specialized `std.algorithm.iteration.sum`.
is there any function that removes double elements in a sorted array?
Sep 06 2015
parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 6 September 2015 at 15:41:34 UTC, Namal wrote:
 is there any function that removes double elements in a sorted 
 array?
std.algorithm.iteration.uniq http://dlang.org/phobos/std_algorithm_iteration.html#uniq
Sep 06 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Sunday, 6 September 2015 at 15:52:38 UTC, anonymous wrote:
 On Sunday, 6 September 2015 at 15:41:34 UTC, Namal wrote:
 is there any function that removes double elements in a sorted 
 array?
std.algorithm.iteration.uniq http://dlang.org/phobos/std_algorithm_iteration.html#uniq
Hmm, I get Error: module comparison is in file 'std/algorithm/comparison.d' which cannot be read import path[0] = /usr/include/dmd/phobos import path[1] = /usr/include/dmd/druntime/import when I try to load the headers like in the example
Sep 06 2015
parent reply "anonymous" <anonymous example.com> writes:
On Sunday, 6 September 2015 at 16:17:29 UTC, Namal wrote:
 Error: module comparison is in file 
 'std/algorithm/comparison.d' which cannot be read
 import path[0] = /usr/include/dmd/phobos
 import path[1] = /usr/include/dmd/druntime/import

 when I try to load the headers like in the example
Are you on 2.066 or older? Back then std.algorithm hasn't been split into submodules yet. Just import std.algorithm then instead of std.algorithm.comparison, std.algorithm.iteration, etc.
Sep 06 2015
parent reply "Namal" <sotis22 mail.ru> writes:
 Are you on 2.066 or older? Back then std.algorithm hasn't been 
 split into submodules yet. Just import std.algorithm then 
 instead of std.algorithm.comparison, std.algorithm.iteration, 
 etc.
Yeah, I just checked, it is 2.066, how can I install the new version on ubuntu with sudo apt-get? I don't realy want to mess with is manually. Also tried just to use algorithm and I get same error message.
Sep 06 2015
parent reply "deed" <none none.none> writes:
On Sunday, 6 September 2015 at 17:57:49 UTC, Namal wrote:

 Yeah, I just checked, it is 2.066,  how can I install the new 
 version on ubuntu with sudo apt-get?
sudo apt-get install dmd will give you dmd v2.067.1. Don't know when it will be upgraded to 2.068 though.
Sep 06 2015
parent reply "Namal" <sotis22 mail.ru> writes:
On Sunday, 6 September 2015 at 20:39:27 UTC, deed wrote:
 On Sunday, 6 September 2015 at 17:57:49 UTC, Namal wrote:

 Yeah, I just checked, it is 2.066,  how can I install the new 
 version on ubuntu with sudo apt-get?
sudo apt-get install dmd will give you dmd v2.067.1. Don't know when it will be upgraded to 2.068 though.
I used the software center to install the newest one. Now it compiles but I have no clue how to use uniq properly. I just tried uniq(sort(arr)); and auto arr = sort(a).uniq!("a==b").array; but I don't get an array with unique elements.
Sep 06 2015
parent reply "cym13" <cpicard openmailbox.org> writes:
On Sunday, 6 September 2015 at 21:01:09 UTC, Namal wrote:
 On Sunday, 6 September 2015 at 20:39:27 UTC, deed wrote:
 On Sunday, 6 September 2015 at 17:57:49 UTC, Namal wrote:

 Yeah, I just checked, it is 2.066,  how can I install the new 
 version on ubuntu with sudo apt-get?
sudo apt-get install dmd will give you dmd v2.067.1. Don't know when it will be upgraded to 2.068 though.
I used the software center to install the newest one. Now it compiles but I have no clue how to use uniq properly. I just tried uniq(sort(arr)); and auto arr = sort(a).uniq!("a==b").array; but I don't get an array with unique elements.
That should be it though... Could you try this minimal complete test? import std.stdio; import std.algorithm; void main(string[] args) { int[] arr = [1, 2, 4, 2, 3, 4, 1]; arr.sort.uniq.writeln; } // [1, 2, 3, 4]
Sep 06 2015
parent reply "Namal" <sotis22 mail.ru> writes:
 That should be it though... Could you try this minimal complete 
 test?

 import std.stdio;
 import std.algorithm;

 void main(string[] args) {
     int[] arr = [1, 2, 4, 2, 3, 4, 1];
     arr.sort.uniq.writeln;
 }

 // [1, 2, 3, 4]
yes, it works likte that. unique(arr) I get Error: undefined identifier 'unique', did you mean template 'uniq(alias pred = "a == b", Range)(Range r) if (isInputRange!Range && is(typeof(binaryFun!pred(r.front, r.front)) == bool))'?
Sep 06 2015
parent reply "cym13" <cpicard openmailbox.org> writes:
On Sunday, 6 September 2015 at 21:18:28 UTC, Namal wrote:
 That should be it though... Could you try this minimal 
 complete test?

 import std.stdio;
 import std.algorithm;

 void main(string[] args) {
     int[] arr = [1, 2, 4, 2, 3, 4, 1];
     arr.sort.uniq.writeln;
 }

 // [1, 2, 3, 4]
yes, it works likte that. unique(arr) I get Error: undefined identifier 'unique', did you mean template 'uniq(alias pred = "a == b", Range)(Range r) if (isInputRange!Range && is(typeof(binaryFun!pred(r.front, r.front)) == bool))'?
Well, if you don't type function names right, it will be hard to help you.
Sep 06 2015
parent reply "Namal" <sotis22 mail.ru> writes:
 Well, if you don't type function names right, it will be hard 
 to help you.
oh, sorry. But I found out what I have been doing wrong besides that. arr.sort.uniq; uniq(arr) or arr.sort.uniq; compiles but doesn't store it in the arr array, I need to store it in a new one.
Sep 06 2015
parent reply "deed" <none none.none> writes:
On Sunday, 6 September 2015 at 22:04:55 UTC, Namal wrote:
 oh, sorry. But I found out what I have been doing wrong besides 
 that.

 arr.sort.uniq;

 uniq(arr) or arr.sort.uniq; compiles but doesn't store it in 
 the arr array, I need to store it in a new one.
Right, it's like int x = 3; // x + 5; // Just an expression evaluated to 8, // but what do you want to do with it? // It won't affect your program and the // compiler will give you an error. int y = x + 5; // But you can assign the expression to // a new variable x = x + 5; // or you can assign it back writeln(x); // or you can pass it to a function. // For your case: int[] arr = [1, 2, 3, 2, 1, 4]; arr.sort; // Operating on arr in place -> arr itself is mutated arr.writeln; // [1, 1, 2, 2, 3, 4] arr.uniq; // Not operating on arr, it's like the expression // x + 5 (but no compiler error is given). arr.uniq.writeln; // [1, 2, 3, 4] (Expression passed to writeln) arr.writeln; // [1, 1, 2, 2, 3, 4] (Not affected) int[] newArr = arr.uniq.array; // Expression put into a new array assigned to newArr newArr.writeln; // [1, 2, 3, 4] arr.writeln; // Still the sorted array. [1, 1, 2, 2, 3, 4] arr = arr.uniq.array; // Now arr is assigned the uniq array arr.writeln; // [1, 2, 3, 4] You need to know whether the function will mutate your array; sort does, while uniq doesn't. If you want to do things requiring mutation, but still want your original data unchanged, you can duplicate the data with .dup before the mutating operations, like this: int[] data = [1, 2, 2, 1]; int[] uniqData = data.dup.sort.uniq.array; data.writeln; // [1, 2, 2, 1] Unchanged, a duplicate was sorted. uniqData.writeln; // [1, 2]
Sep 07 2015
next sibling parent reply "deed" <none none.none> writes:
On Monday, 7 September 2015 at 10:25:09 UTC, deed wrote:
 writeln(x);    // or you can pass it to a function.
I meant `writeln(x + 5)`
Sep 07 2015
next sibling parent reply "Namal" <sotis22 mail.ru> writes:
On Monday, 7 September 2015 at 10:28:20 UTC, deed wrote:
 On Monday, 7 September 2015 at 10:25:09 UTC, deed wrote:
 writeln(x);    // or you can pass it to a function.
I meant `writeln(x + 5)`
If I have just red your post before I started using reverse on dynamic arrays... Anyway, there is no .reverse for strings I guess, what is the way to completely reverse a string in D?
Sep 12 2015
parent reply deed <none none.none> writes:
On Saturday, 12 September 2015 at 12:51:04 UTC, Namal wrote:
 Anyway, there is no .reverse for strings I guess, what is the 
 way to completely reverse a string in D?
What do you want to do? Do you want to keep your data in original order, but get a reversed view of it for something, or do you actually want to reverse your original array? You can use `retro` to simply read your array backwards, i.e.: string s = "Some text"; s.retro.writeln; // `txet emoS` s.writeln; // `Some text` s.retro.find("e"); // `Some te` (Surprising to me. Error? 2.067.1) s.retro.until("e").writeln;// `tx` s.find("e"); // `Some` The string is still kept in original order, but `retro` returns a range reading the array backwards. If you want to store a reversed string in memory, that's possible too, of course. One way of doing it, is to convert your retro range to a string: s = s.retro.to!string; s.writeln; // `txet emoS` This will allocate new memory for the reversed copy and assign it to `s`. Reverse is an algorithm that swaps values at different indices and since `string` is an alias for `const(char)[]`, it's not allowed. It means that each element of the array is const, so you cannot mutate any elements, but you can append or remove elements or assign the slice to view another part of the string or some other string. Hence, a `s.reverse` will give you an error. If you use `char[]` instead of `const(char)[]` you can use reverse and reuse the same memory for the reversed `char[]`. To illustrate: char[] t = ['a', 'b', 'c']; std.algorithm.reverse(t); t.writeln; // `cba` // s[0] = s[$-1]; // Error, cannot mutate const elements auto r = s.retro; s.length = 0; r.each!(e => s ~= e); s.writeln; // s has the reversed string, obtained through // a temporary range object, setting length to // zero and appending the elements from the // range, which is allowed for const(char)[]
Sep 12 2015
next sibling parent deed <none none.none> writes:
On Sunday, 13 September 2015 at 03:20:31 UTC, deed wrote:
 string s = "Some text";
 s.retro.find("e");         // `Some te` (Surprising to me. 
 Error? 2.067.1)
Sorry, the above is wrong, .retro.find does indeed return what's expected. string s = "Some text"; s.retro.find("e").writeln; // Prints `et emoS`, as expected.
Sep 13 2015
prev sibling parent deed <none none.none> writes:
On Sunday, 13 September 2015 at 03:20:31 UTC, deed wrote:
 ...
 and since `string` is an alias for `const(char)[]`, it's not ...
string is an alias for immutable(char)[], not const(char)[]. http://dlang.org/arrays.html#strings Sorry about the noise.
Sep 13 2015
prev sibling parent reply Namal <sotis22 mail.ru> writes:
Hello guys, is there a nice functional way to read the file which 
is like


1,2,3,4,5,6
2,3,4,5,6,7
8,9,0,9,2,3

line by line, split numbers and remove each ','
convert it to int and save in a matrix int[][] arr?
Sep 18 2015
parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Friday, 18 September 2015 at 10:26:46 UTC, Namal wrote:
 Hello guys, is there a nice functional way to read the file 
 which is like


 1,2,3,4,5,6
 2,3,4,5,6,7
 8,9,0,9,2,3

 line by line, split numbers and remove each ','
 convert it to int and save in a matrix int[][] arr?
Not tested, but I think the following should work: auto matrix = str .byLine .map!((l) => l.split(",") // Split each line .map!(to!int) // Turn into ints .array) // Return an array .array // Copy into an array
Sep 18 2015
parent reply Namal <sotis22 mail.ru> writes:
On Friday, 18 September 2015 at 10:34:41 UTC, Edwin van Leeuwen 
wrote:
 On Friday, 18 September 2015 at 10:26:46 UTC, Namal wrote:
 Hello guys, is there a nice functional way to read the file 
 which is like


 1,2,3,4,5,6
 2,3,4,5,6,7
 8,9,0,9,2,3

 line by line, split numbers and remove each ','
 convert it to int and save in a matrix int[][] arr?
Not tested, but I think the following should work: auto matrix = str .byLine .map!((l) => l.split(",") // Split each line .map!(to!int) // Turn into ints .array) // Return an array .array // Copy into an array
And how do tell here to read my file?
Sep 18 2015
parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Friday, 18 September 2015 at 10:48:25 UTC, Namal wrote:
 On Friday, 18 September 2015 at 10:34:41 UTC, Edwin van Leeuwen 
 wrote:
 On Friday, 18 September 2015 at 10:26:46 UTC, Namal wrote:
 Hello guys, is there a nice functional way to read the file 
 which is like


 1,2,3,4,5,6
 2,3,4,5,6,7
 8,9,0,9,2,3

 line by line, split numbers and remove each ','
 convert it to int and save in a matrix int[][] arr?
Not tested, but I think the following should work: auto matrix = str .byLine .map!((l) => l.split(",") // Split each line .map!(to!int) // Turn into ints .array) // Return an array .array // Copy into an array
And how do tell here to read my file?
Replace str with File("myfile"): auto matrix = File("myfile") .byLine .map!((l) => l.split(",") // Split each line .map!(to!int) // Turn into ints .array) // Return an array .array // Copy into an array
Sep 18 2015
parent reply Namal <sotis22 mail.ru> writes:
On Friday, 18 September 2015 at 11:06:46 UTC, Edwin van Leeuwen 
wrote:
 On Friday, 18 September 2015 at 10:48:25 UTC, Namal wrote:
 On Friday, 18 September 2015 at 10:34:41 UTC, Edwin van 
 Leeuwen wrote:
 On Friday, 18 September 2015 at 10:26:46 UTC, Namal wrote:
 Hello guys, is there a nice functional way to read the file 
 which is like


 1,2,3,4,5,6
 2,3,4,5,6,7
 8,9,0,9,2,3

 line by line, split numbers and remove each ','
 convert it to int and save in a matrix int[][] arr?
Not tested, but I think the following should work: auto matrix = str .byLine .map!((l) => l.split(",") // Split each line .map!(to!int) // Turn into ints .array) // Return an array .array // Copy into an array
And how do tell here to read my file?
Replace str with File("myfile"): auto matrix = File("myfile") .byLine .map!((l) => l.split(",") // Split each line .map!(to!int) // Turn into ints .array) // Return an array .array // Copy into an array
import std.file, std.stdio, std.string, std.conv, std.algorithm, std.array; void main(){ auto matrix = File("test.txt") .byLine .map!((l) => l.split(",") // Split each line .map!(to!int) // Turn into ints .array) // Return an array .array(); matrix.writeln; } compiles but crashes
Sep 18 2015
parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Friday, 18 September 2015 at 11:11:51 UTC, Namal wrote:
 compiles but crashes
For me it works fine. You probably have extra spaces or something in your file. It would help if you posted the error message you get when running the program.
Sep 18 2015
next sibling parent Namal <sotis22 mail.ru> writes:
On Friday, 18 September 2015 at 11:37:15 UTC, Edwin van Leeuwen 
wrote:
 On Friday, 18 September 2015 at 11:11:51 UTC, Namal wrote:
 compiles but crashes
For me it works fine. You probably have extra spaces or something in your file. It would help if you posted the error message you get when running the program.
Oh, yes, sorry, there was a space after the end of one line
Sep 18 2015
prev sibling parent reply Namal <sotis22 mail.ru> writes:
So do I understand it right: does  => in map! indicates a lambda 
function?
Sep 18 2015
parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Friday, 18 September 2015 at 12:28:29 UTC, Namal wrote:
 So do I understand it right: does  => in map! indicates a 
 lambda function?
Yes exactly. There are a number of ways you can define a lambda function in D. For example if the function is multiline I often use: (l) { ...; // do something return result; } More details here http://ddili.org/ders/d.en/lambda.html (half way down the page)
Sep 18 2015
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 09/18/2015 05:58 AM, Edwin van Leeuwen wrote:
 On Friday, 18 September 2015 at 12:28:29 UTC, Namal wrote:
 So do I understand it right: does  => in map! indicates a lambda
 function?
Yes exactly. There are a number of ways you can define a lambda function in D. For example if the function is multiline I often use: (l) { ...; // do something return result; } More details here http://ddili.org/ders/d.en/lambda.html (half way down the page)
As of a few hours ago, you can go to the book index and search for =>, or lambda, or anything else. :) http://ddili.org/ders/d.en/ix.html (Excuse the page format for now.) Ali
Sep 18 2015
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Monday, 7 September 2015 at 10:25:09 UTC, deed wrote:
 Right, it's like

 int x = 3;
 // x + 5;      // Just an expression evaluated to 8,
                // but what do you want to do with it?
                // It won't affect your program and the
                // compiler will give you an error.

 int y = x + 5; // But you can assign the expression to
                // a new variable
 x = x + 5;     // or you can assign it back
 writeln(x);    // or you can pass it to a function.


 // For your case:

 int[] arr = [1, 2, 3, 2, 1, 4];
 arr.sort;          // Operating on arr in place -> arr itself 
 is mutated
 arr.writeln;       // [1, 1, 2, 2, 3, 4]
 arr.uniq;          // Not operating on arr, it's like the 
 expression
                    // x + 5 (but no compiler error is given).
 arr.uniq.writeln;  // [1, 2, 3, 4] (Expression passed to 
 writeln)
 arr.writeln;       // [1, 1, 2, 2, 3, 4] (Not affected)

 int[] newArr = arr.uniq.array;
                    // Expression put into a new array assigned 
 to newArr
 newArr.writeln;    // [1, 2, 3, 4]
 arr.writeln;       // Still the sorted array. [1, 1, 2, 2, 3, 4]
 arr = arr.uniq.array; // Now arr is assigned the uniq array
 arr.writeln;       // [1, 2, 3, 4]


 You need to know whether the function will mutate your array; 
 sort does, while uniq doesn't. If you want to do things 
 requiring mutation, but still want your original data 
 unchanged, you can duplicate the data with .dup before the 
 mutating operations, like this:

 int[] data = [1, 2, 2, 1];
 int[] uniqData = data.dup.sort.uniq.array;
 data.writeln;      // [1, 2, 2, 1] Unchanged, a duplicate was 
 sorted.
 uniqData.writeln;  // [1, 2]
As an aside, you should use `sort()` instead of the parentheses-less `sort`. The reason for this is that doing `arr.sort` invokes the old builtin array sorting which is terribly slow, whereas `import std.algorithm; arr.sort()` uses the much better sorting algorithm defined in Phobos.
Sep 14 2015
parent deed <none none.none> writes:
On Monday, 14 September 2015 at 18:36:54 UTC, Meta wrote:
 As an aside, you should use `sort()` instead of the 
 parentheses-less `sort`. The reason for this is that doing 
 `arr.sort` invokes the old builtin array sorting which is 
 terribly slow, whereas `import std.algorithm; arr.sort()` uses 
 the much better sorting algorithm defined in Phobos.
Thanks for pointing out.
Sep 14 2015
prev sibling parent reply Namal <sotis22 mail.ru> writes:
On Saturday, 5 September 2015 at 14:49:13 UTC, deed wrote:
 On Saturday, 5 September 2015 at 14:44:19 UTC, deed wrote:
  .map!(s => chomp(s, "\"")
  .map!(s => chompPrefix(s, "\"")
should be .map!(s => chomp(s, "\"")) .map!(s => chompPrefix(s, "\""))
Hello again, Now I have a file that looks like a b c d e f g h .... I want to get that in an element of strings but without quatation marks auto a = f.byLine() .map!(a => a.split) .array(); f.close();
Nov 07 2015
parent Namal <sotis22 mail.ru> writes:
On Saturday, 7 November 2015 at 17:13:33 UTC, Namal wrote:
 On Saturday, 5 September 2015 at 14:49:13 UTC, deed wrote:
 On Saturday, 5 September 2015 at 14:44:19 UTC, deed wrote:
  .map!(s => chomp(s, "\"")
  .map!(s => chompPrefix(s, "\"")
should be .map!(s => chomp(s, "\"")) .map!(s => chompPrefix(s, "\""))
Hello again, Now I have a file that looks like a b c d e f g h .... I want to get that in an element of strings but without quatation marks auto a = f.byLine() .map!(a => a.split) .array(); f.close();
Sorry for double post, I pressed accidently 'enter'. How can I ad chomp so the quatation marks are removed?
Nov 07 2015
prev sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Sep 03, 2015 at 11:28:36PM +0000, Namal via Digitalmars-d-learn wrote:
 On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson wrote:
And also:
import std.algorithm

Sorry, I should have taken the time to answer properly and fully.
import std.file, std.stdio, std.string, std.conv, std.algorithm; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array(); writeln(numbers); } Error: no property 'array' for type 'MapResult!(__lambda2, MapResult!(__lambda1, ByLine!(char, char)))' Still an error.
import std.array : array; T -- Do not reason with the unreasonable; you lose by definition.
Sep 03 2015