digitalmars.D.learn - appender!(dchar[]) put fail
- kerdemdemir (94/94) Jun 13 2015 I have two strings(stringB,stringC) which I need to repeat(bCount
- Quentin Ladeveze (9/103) Jun 13 2015 The problem is that your appender is a char appender, and you try
- kerdemdemir (7/15) Jun 13 2015 But I can see in the example of
- Quentin Ladeveze (7/26) Jun 13 2015 It is the same, but totalStr is not a dchar[]. It's a Result (a
- kerdemdemir (4/10) Jun 13 2015 Sorry to making the discussion longer and wasting your times.
- Dennis Ritchie (11/15) Jun 13 2015 Maybe it fit?
- kerdemdemir (17/26) Jun 13 2015 Thanks lot that is really good.
- Quentin Ladeveze (4/20) Jun 13 2015 Two functions doing the same thing would be the illogical thing,
- Dennis Ritchie (6/21) Jun 13 2015 std.range.repeat is a lazy version unlike std.array.replicate:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (9/17) Jun 13 2015 To answer Erdem's later question, loops with side effects can be
- Steven Schveighoffer (7/21) Jun 13 2015 Have you tried:
I have two strings(stringB,stringC) which I need to repeat(bCount times, cCountTimes) and then chain. auto charAppender = appender!(dchar[]); auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); This compiles and works ok, But when I try to append new string to charAppender : charAppender.put(totalStr); Error: template std.array.join cannot deduce function from argument types I tried: charAppender.put(totalStr.array()); charAppender.data.chain(totalStr); charAppender.data.chain(totalStr.array()); etc... I always get compile errors. Do you have any idea or fix about that? Also what is the difference between algorithm.joiner without seperator and range.chain? //////////////////////////////////////////////////////////////////////////// As requested before, this time I will copy full code, //////////////////////////////////////////////////////////////////////////// int[dchar] mapA; int includeCounter(T)(T tuple) { int curMax = 100000; foreach ( elem ; tuple ) { int numberInA = 0; if (elem[0] in mapA) numberInA = mapA[elem[0]] ; else { curMax = 0; break; } if ( numberInA < elem[1] ) { curMax = 0; break; } else { auto newCount = numberInA / elem[1]; if ( newCount < curMax ) curMax = newCount; } } if (curMax > 0) { foreach ( elem ; tuple ) { mapA[elem[0]] -= curMax; } } return curMax; } void readInput() { size_t lineSize; auto stringA = stdin.readln.chomp().map!( a => to!dchar(a)).array(); auto stringB = stdin.readln.chomp().map!( a => to!dchar(a)).array(); auto stringC = stdin.readln.chomp().map!( a => to!dchar(a)).array(); foreach ( elem ; stringA) mapA[elem]++; auto tupleB = stringB.group(); auto tupleC = stringC.group(); auto bCount = includeCounter( tupleB ); auto cCount = includeCounter( tupleC ); auto charAppender = appender!(dchar[]); foreach ( elem ; mapA.keys) { int* count = &mapA[elem]; if ( *count > 0) { while((*count)--) charAppender.put(elem) ; } } auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); charAppender.put(totalStr); } void main( string[] args ) { readInput(); }
Jun 13 2015
On Saturday, 13 June 2015 at 10:45:58 UTC, kerdemdemir wrote:I have two strings(stringB,stringC) which I need to repeat(bCount times, cCountTimes) and then chain. auto charAppender = appender!(dchar[]); auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); This compiles and works ok, But when I try to append new string to charAppender : charAppender.put(totalStr); Error: template std.array.join cannot deduce function from argument types I tried: charAppender.put(totalStr.array()); charAppender.data.chain(totalStr); charAppender.data.chain(totalStr.array()); etc... I always get compile errors. Do you have any idea or fix about that? Also what is the difference between algorithm.joiner without seperator and range.chain? //////////////////////////////////////////////////////////////////////////// As requested before, this time I will copy full code, //////////////////////////////////////////////////////////////////////////// int[dchar] mapA; int includeCounter(T)(T tuple) { int curMax = 100000; foreach ( elem ; tuple ) { int numberInA = 0; if (elem[0] in mapA) numberInA = mapA[elem[0]] ; else { curMax = 0; break; } if ( numberInA < elem[1] ) { curMax = 0; break; } else { auto newCount = numberInA / elem[1]; if ( newCount < curMax ) curMax = newCount; } } if (curMax > 0) { foreach ( elem ; tuple ) { mapA[elem[0]] -= curMax; } } return curMax; } void readInput() { size_t lineSize; auto stringA = stdin.readln.chomp().map!( a => to!dchar(a)).array(); auto stringB = stdin.readln.chomp().map!( a => to!dchar(a)).array(); auto stringC = stdin.readln.chomp().map!( a => to!dchar(a)).array(); foreach ( elem ; stringA) mapA[elem]++; auto tupleB = stringB.group(); auto tupleC = stringC.group(); auto bCount = includeCounter( tupleB ); auto cCount = includeCounter( tupleC ); auto charAppender = appender!(dchar[]); foreach ( elem ; mapA.keys) { int* count = &mapA[elem]; if ( *count > 0) { while((*count)--) charAppender.put(elem) ; } } auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); charAppender.put(totalStr); } void main( string[] args ) { readInput(); }The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work.
Jun 13 2015
The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work.But I can see in the example of array.appander(http://dlang.org/phobos/std_array.html#appender) int[] a = [ 1, 2 ]; auto app2 = appender(a); app2.put(3); app2.put([ 4, 5, 6 ]); ---> appender accepts another array. Why this is not same with dchar ?
Jun 13 2015
On Saturday, 13 June 2015 at 12:02:10 UTC, kerdemdemir wrote:It is the same, but totalStr is not a dchar[]. It's a Result (a type internal to the chain function ) which is a range. The foreach loop iterates over Result, which returns dchar[]. So if you try to do something like that : charAppender.put(totalStr.array), it won't work because totalStr.array is a dchar[][].The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work.But I can see in the example of array.appander(http://dlang.org/phobos/std_array.html#appender) int[] a = [ 1, 2 ]; auto app2 = appender(a); app2.put(3); app2.put([ 4, 5, 6 ]); ---> appender accepts another array. Why this is not same with dchar ?
Jun 13 2015
It is the same, but totalStr is not a dchar[]. It's a Result (a type internal to the chain function ) which is a range. The foreach loop iterates over Result, which returns dchar[]. So if you try to do something like that : charAppender.put(totalStr.array), it won't work because totalStr.array is a dchar[][].Sorry to making the discussion longer and wasting your times. But I am looking for a way without for loops. Also looping every element one by one does not seems very efficient to me. Any advices for that?
Jun 13 2015
On Saturday, 13 June 2015 at 13:01:29 UTC, kerdemdemir wrote:Sorry to making the discussion longer and wasting your times. But I am looking for a way without for loops. Also looping every element one by one does not seems very efficient to me. Any advices for that?Maybe it fit? auto stringB = readln.chomp.map!(to!dchar).array; auto stringC = readln.chomp.map!(to!dchar).array; auto charAppender = appender!(dchar[][]); auto totalStr = stringB.repeat(3).chain(stringC.repeat(5)); charAppender.put(totalStr); writeln(charAppender); charAppender.put("c"d.dup); charAppender.put("test"d.dup); writeln(charAppender);
Jun 13 2015
On Saturday, 13 June 2015 at 13:09:20 UTC, Dennis Ritchie wrote:auto stringB = readln.chomp.map!(to!dchar).array; auto stringC = readln.chomp.map!(to!dchar).array; auto charAppender = appender!(dchar[][]); auto totalStr = stringB.repeat(3).chain(stringC.repeat(5)); charAppender.put(totalStr); writeln(charAppender); charAppender.put("c"d.dup); charAppender.put("test"d.dup); writeln(charAppender);Thanks lot that is really good. One more question I am asking those kind of questions to understand and not ask same stuff over and over, : auto totalStr = chain(stringB.replicate(bCount), stringC.replicate(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[] But auto totalStr = chain(stringB.repeat(bCount), stringC.repeat(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[][] It seems to me a little inconsistent. range.repeat and array.replicate gives result in difference dimension. Is there any explanation or logic that I am missing which results this behaviour?
Jun 13 2015
On Saturday, 13 June 2015 at 13:32:19 UTC, kerdemdemir wrote:Thanks lot that is really good. One more question I am asking those kind of questions to understand and not ask same stuff over and over, :Don't worry, there is "learn" in "D.learn"auto totalStr = chain(stringB.replicate(bCount), stringC.replicate(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[] But auto totalStr = chain(stringB.repeat(bCount), stringC.repeat(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[][] It seems to me a little inconsistent. range.repeat and array.replicate gives result in difference dimension. Is there any explanation or logic that I am missing which results this behaviour?Two functions doing the same thing would be the illogical thing, no ?
Jun 13 2015
On Saturday, 13 June 2015 at 13:32:19 UTC, kerdemdemir wrote:One more question I am asking those kind of questions to understand and not ask same stuff over and over, : auto totalStr = chain(stringB.replicate(bCount), stringC.replicate(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[] But auto totalStr = chain(stringB.repeat(bCount), stringC.repeat(cCount)); writeln(typeof(totalStr.array()).stringof); ---->dchar[][] It seems to me a little inconsistent. range.repeat and array.replicate gives result in difference dimension. Is there any explanation or logic that I am missing which results this behaviour?std.range.repeat is a lazy version unlike std.array.replicate: 5.repeat(3).writeln; // a lazy version // [5, 5, 5] [5].replicate(3).writeln; // [5, 5, 5] // but [5].repeat(3).writeln; // a lazy version // [[5], [5], [5]]
Jun 13 2015
On 06/13/2015 04:23 AM, Quentin Ladeveze wrote:The problem is that your appender is a char appender, and you try to put a dstring into it. Replace : charAppender.put(totalStr); by : foreach(elem; totalStr){ charAppender.put(elem); } elem will be a dchar, so it will work.To answer Erdem's later question, loops with side effects can be replaced with std.algorithm.each: totalStr.each!(elem => charAppender.put(elem)); One issue with that method that I am frequently reminded of is that although the lambda's => syntax is by definition a return statement, 'each' does not do anything with the returned value. (Regardless of whether the lambda returns anything or not.) Ali
Jun 13 2015
On 6/13/15 6:45 AM, kerdemdemir wrote:I have two strings(stringB,stringC) which I need to repeat(bCount times, cCountTimes) and then chain. auto charAppender = appender!(dchar[]); auto totalStr = stringB.repeat(bCount).chain(stringC.repeat(cCount)); This compiles and works ok, But when I try to append new string to charAppender : charAppender.put(totalStr); Error: template std.array.join cannot deduce function from argument types I tried: charAppender.put(totalStr.array()); charAppender.data.chain(totalStr); charAppender.data.chain(totalStr.array()); etc... I always get compile errors. Do you have any idea or fix about that?Have you tried: put(charAppender, totalStr); It is not recommended to use charAppender.put directly, unless you know it will work. This is a frequent cause of problems (using .put on an output range directly). -Steve
Jun 13 2015