| Thread overview | ||||||
|---|---|---|---|---|---|---|
|
March 08, 2014 linear search using 'find' on an array of structs? | ||||
|---|---|---|---|---|
| ||||
import std.container: find, equal, empty;
import std.container : SList;
struct c
{
int idx;
string name;
}
c[] clist = [ {1, "name1"}, {2, "name2"}, { 3, "name3" } ];
// c* clist = [ {1, "name1"}, {2, "name2"}, { 3, "name3" } ];
int
main()
{
// Case-insensitive find of a string
string[] s = [ "Hello", "world", "!" ];
assert(!find!("toLower(a) == b")(s, "hello").empty);
assert(!find!("toLower(a) == b")(clist.name, "name2").empty);
return 0;
}
I went looking to replace several foreach statements. Can 'find' (in understand it's just a linear search) be used on an array of structures like above.
Example pulled and modified. Above code gives me (naturally) -
... no property 'name' for type 'cp[]'.
Interestingly, I had accidentally coded the commented out line before and it compiles correctly but will (as you guessed it) fail.
Sorry for the basics...
| ||||
March 09, 2014 Re: linear search using 'find' on an array of structs? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to captain_fid | On Saturday, 8 March 2014 at 18:08:44 UTC, captain_fid wrote:
> import std.container: find, equal, empty;
> import std.container : SList;
>
> struct c
> {
> int idx;
> string name;
> }
>
> c[] clist = [ {1, "name1"}, {2, "name2"}, { 3, "name3" } ];
> // c* clist = [ {1, "name1"}, {2, "name2"}, { 3, "name3" } ];
>
> int
> main()
> {
> // Case-insensitive find of a string
> string[] s = [ "Hello", "world", "!" ];
> assert(!find!("toLower(a) == b")(s, "hello").empty);
>
> assert(!find!("toLower(a) == b")(clist.name, "name2").empty);
> return 0;
> }
>
> I went looking to replace several foreach statements. Can 'find' (in understand it's just a linear search) be used on an array of structures like above.
>
> Example pulled and modified. Above code gives me (naturally) -
> ... no property 'name' for type 'cp[]'.
>
> Interestingly, I had accidentally coded the commented out line before and it compiles correctly but will (as you guessed it) fail.
>
> Sorry for the basics...
import std.container;
import std.algorithm;
import std.array;
import std.range;
import std.stdio;
struct C
{
int idx;
string name;
bool opEquals()(auto ref const C v) const {
return v.idx == this.idx;
}
int opCmp(ref const C v) {
return v.idx == this.idx;
}
}
int main()
{
C[] d = [ {1, "name1"}, {2, "name2"}, { 3, "name3" } ];
auto r = assumeSorted(d);
assert(r.canFind(C(3, "")));
assert(!r.canFind(C(32,"")));
writeln( r.find(C(2, "")));
return 0;
}
// yields ....
// [C(2, "name2"), C(3, "name3") ]
Well, I see that both opEquals and opCmp needed to be overridden.
But it's odd that C(3, "name3") is returned as well as C(2, "name2"). And the "" is ugly...
Any suggestions would be helpful.
| |||
March 09, 2014 Re: linear search using 'find' on an array of structs? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to captain_fid Attachments:
| > assert(!find!("toLower(a) == b")(s, "hello").empty); > > assert(!find!("toLower(a) == b")(clist.name, "name2").empty); > But clist is an array of c's, it has no `.name` field by itself. So, put the `.name` call inside the comparator: assert( find!("toLower(a.name) == b")(clist <http://clist.name/>*,* "name2").empty); This gives me this code: import std.algorithm: find; import std.array: empty; import std.uni: toLower; struct C // Use UpperCase for you user-defined types { int idx; string name; } C[] clist = [ {1, "name1"}, {2, "name2"}, { 3, "name3" } ]; void main() // no need to return 0 { auto target = clist.find!((a,b) => toLower(a.name) == b)("name2"); assert(!target.empty); } Using UFCS (Universal Function Call Syntax) to tranform f(a,b) into a.f(b). I used it on `find`. > I went looking to replace several foreach statements. Can 'find' (in understand it's just a linear search) be used on an array of structures like above. > Sure, as long as you tell it how you will get the info from the range (it defaults to simple equality). > > Example pulled and modified. Above code gives me (naturally) - > ... no property 'name' for type 'cp[]'. > > Interestingly, I had accidentally coded the commented out line before and it compiles correctly but will (as you guessed it) fail. > I never use pointers in D. I suppose the `.name` call is propagated to the array elements? | |||
March 10, 2014 Re: linear search using 'find' on an array of structs? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | On Sunday, 9 March 2014 at 10:46:26 UTC, Philippe Sigaud wrote:
>> assert(!find!("toLower(a) == b")(s, "hello").empty);
>>
>> assert(!find!("toLower(a) == b")(clist.name, "name2").empty);
>>
>
> But clist is an array of c's, it has no `.name` field by itself. So, put
> the `.name` call inside the comparator:
>
>
> assert( find!("toLower(a.name) == b")(clist <http://clist.name/>*,*
> "name2").empty);
>
> This gives me this code:
>
> import std.algorithm: find;
> import std.array: empty;
> import std.uni: toLower;
>
> struct C // Use UpperCase for you user-defined types
> {
> int idx;
> string name;
> }
>
> C[] clist = [ {1, "name1"}, {2, "name2"}, { 3, "name3" } ];
>
> void main() // no need to return 0
> {
> auto target = clist.find!((a,b) => toLower(a.name) == b)("name2");
> assert(!target.empty);
> }
>
> Using UFCS (Universal Function Call Syntax) to tranform f(a,b) into a.f(b).
> I used it on `find`.
>
>
>
>> I went looking to replace several foreach statements. Can 'find' (in
>> understand it's just a linear search) be used on an array of structures
>> like above.
>>
>
> Sure, as long as you tell it how you will get the info from the range (it
> defaults to simple equality).
>
>
>
>>
>> Example pulled and modified. Above code gives me (naturally) -
>> ... no property 'name' for type 'cp[]'.
>>
>> Interestingly, I had accidentally coded the commented out line before and
>> it compiles correctly but will (as you guessed it) fail.
>>
>
> I never use pointers in D. I suppose the `.name` call is propagated to the
> array elements?
Thanks for the simple explanation Phillppe. Someone else mentioned before not using pointers in D (the loss of array goodness like mentioned in Andrei's book). Bad habits...
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply