December 30, 2019
On Monday, 30 December 2019 at 19:08:27 UTC, Ron Tarrant wrote:
> On Monday, 30 December 2019 at 17:12:26 UTC, MoonlightSentinel wrote:
>
>> D disallows implicit conversion from integers to pointers and hence they cannot be compared. You would need to explicitly cast your ulong to an appropriate pointer type
>
> I'm not trying to convert, just wade through an array of pointers to find a specific pointer using searchUntil().
>
> I mean, it's not a big deal if I can't do it.

You can definitely do it:

  $ rdmd --eval 'int a, b, c; [&a, &b, &c].countUntil(&c).writeln'
  2

But you need to have an array of pointers.
December 30, 2019
On Monday, 30 December 2019 at 19:39:04 UTC, mipri wrote:
> You can definitely do it:
>
>   $ rdmd --eval 'int a, b, c; [&a, &b, &c].countUntil(&c).writeln'
>   2
>
> But you need to have an array of pointers.

Thanks, mipri. Got it sorted. Here's a working proof...

```
import std.stdio;
import std.algorithm;
import std.conv;

void main(string[] args)
{
	MyObject[] objectArray;
	MyObject newObject;
	MyObject findPointer;
	long index;
	
	int lastObjectID = 7;
	int foundObjectIndex;
	
	for(int i; i < 12; i++)
	{
		lastObjectID++;
		newObject = new MyObject(lastObjectID);
		objectArray ~= newObject;
		
		if(i is 5)
		{
			findPointer = newObject;
		}
	}
	
	for(int i; i < objectArray.length; i++)
	{
		writeln("object: ", cast(MyObject*)objectArray[i], ", ID: ", objectArray[i].objectID);
	}
	
	index = objectArray.countUntil(findPointer);
	writeln("findPointer: ", findPointer, ", at address: ", cast(MyObject*)findPointer, " is a MyObject pointer in the objectArray with an index of ", index, ", address: ", cast(MyObject*)objectArray[index], ", ID: ", objectArray[index].objectID);
	
} // main()


class MyObject
{
	int objectID;
	
	this(int ordinal)
	{
		objectID = ordinal;
		
	} // this()
	
} // class MyObject

```

December 30, 2019
On Monday, 30 December 2019 at 19:46:50 UTC, Ron Tarrant wrote:

> Thanks, mipri. Got it sorted. Here's a working proof...

Forgot to show the output:

object: 17B0A831000, ID: 8
object: 17B0A831020, ID: 9
object: 17B0A831060, ID: 10
object: 17B0A831080, ID: 11
object: 17B0A8310A0, ID: 12
object: 17B0A8310C0, ID: 13
object: 17B0A8310E0, ID: 14
object: 17B0A831100, ID: 15
object: 17B0A831120, ID: 16
object: 17B0A831140, ID: 17
object: 17B0A831160, ID: 18
object: 17B0A831180, ID: 19
findPointer: find_in_array_object.MyObject, at address: 17B0A8310C0 is a MyObject pointer in the objectArray with an index of 5, address: 17B0A8310C0, ID: 13
December 30, 2019
On Monday, 30 December 2019 at 19:46:50 UTC, Ron Tarrant wrote:
> Thanks, mipri. Got it sorted. Here's a working proof...
>
> ```
> import std.stdio;
> import std.algorithm;
> import std.conv;
>
> void main(string[] args)
> {
> 	MyObject[] objectArray;
> 	MyObject newObject;
> 	MyObject findPointer;
> 	long index;
> 	
> 	int lastObjectID = 7;
> 	int foundObjectIndex;
> 	
> 	for(int i; i < 12; i++)
> 	{
> 		lastObjectID++;
> 		newObject = new MyObject(lastObjectID);
> 		objectArray ~= newObject;
> 		
> 		if(i is 5)
> 		{
> 			findPointer = newObject;
> 		}
> 	}
> 	
> 	for(int i; i < objectArray.length; i++)
> 	{
> 		writeln("object: ", cast(MyObject*)objectArray[i], ", ID: ", objectArray[i].objectID);
> 	}
> 	
> 	index = objectArray.countUntil(findPointer);
> 	writeln("findPointer: ", findPointer, ", at address: ", cast(MyObject*)findPointer, " is a MyObject pointer in the objectArray with an index of ", index, ", address: ", cast(MyObject*)objectArray[index], ", ID: ", objectArray[index].objectID);
> 	
> } // main()
>
>
> class MyObject
> {
> 	int objectID;
> 	
> 	this(int ordinal)
> 	{
> 		objectID = ordinal;
> 		
> 	} // this()
> 	
> } // class MyObject
>
> ```

Compare:

  import std.stdio;
  import std.algorithm;
  import std.conv;

  void main(string[] args)
  {
  	MyObject[] objectArray;
  	MyObject newObject;
  	MyObject findPointer;
  	long index;

  	int foundObjectIndex;

  	for(int i; i < 12; i++)
  	{
  		newObject = new MyObject();
  		objectArray ~= newObject;

  		if(i is 5)
  		{
  			findPointer = newObject;
  		}
  	}

  	for(int i; i < objectArray.length; i++)
  	{
  		writeln("object: ", cast(MyObject*)objectArray[i]);
  	}

  	index = objectArray.countUntil(findPointer);
  	writeln("findPointer: ", findPointer, ", at address: ", cast(MyObject*)findPointer, " is a MyObject pointer in the objectArray with an index of ", index, ", address: ", cast(MyObject*)objectArray[index]);

  } // main()


  class MyObject {}

With output:

  object: 7F2DC37C3000
  object: 7F2DC37C3020
  object: 7F2DC37C3030
  object: 7F2DC37C3040
  object: 7F2DC37C3050
  object: 7F2DC37C3060
  object: 7F2DC37C3070
  object: 7F2DC37C3080
  object: 7F2DC37C3090
  object: 7F2DC37C30A0
  object: 7F2DC37C30B0
  object: 7F2DC37C30C0
  findPointer: x297.MyObject, at address: 7F2DC37C3060 is a MyObject pointer in the objectArray with an index of 5, address: 7F2DC37C3060

December 30, 2019
On Sunday, 29 December 2019 at 08:31:13 UTC, mipri wrote:
>
> int i = a.countUntil!(v => v == 55);
> assert(i == 2);

I also had to ask because I couldn't find it. In other languages it's named "index()", "indexOf()" or "find()". D is the only language I know which uses the "countUntil" scheme. And even so it's not obvious from the name if it's the index of the element or number of preceding elements.

December 31, 2019
On Monday, 30 December 2019 at 23:15:48 UTC, JN wrote:
> On Sunday, 29 December 2019 at 08:31:13 UTC, mipri wrote:
>>
>> int i = a.countUntil!(v => v == 55);
>> assert(i == 2);
>
> I also had to ask because I couldn't find it. In other languages it's named "index()", "indexOf()" or "find()". D is the only language I know which uses the "countUntil" scheme. And even so it's not obvious from the name if it's the index of the element or number of preceding elements.


I had first tried myarray.index(myvalue) because I coulda sworn I wrote exactly that syntax a only a few days ago.  But I've been hopping between languages, some D, some Crystal, some C++, some Javascript, and with only two cerebral hemispheres, maybe I got confused. So, D doesn't have index()?  Is it called find()?  Something else?  It was hard to find the right stuff in the documentation.

So now I know about countUntil, and I'm glad the question has gotten some traction for others to make progress with their code.  I'm needing to see more examples.  It might have something to do with the array I'm working with being inside a foreach loop. My code looks like this, with the problematic line duplicated to show some of the variations I tried:

    import std.algorithm;

    alias doo = ubyte;
    struct Info
    {
        int x;
        doo[NDOOS] doos;   // NDOOS = 10
    }

    immutable int INFO = 100000;
    Info[NINFOS]  infos;    // global array, used heavily.

    float foo_function(doo important_d)    {
      ...
      foreach (info; infos)    {

        int i = info.doos.index(important_d);                  // #1
        int i = info.doos.countUntil(d => d == important_d);   // #2
        int i = info.doos.countUntil!(d => d == important_d);  // #3
        int i = countUntil(d => d == important_d, info.doos);  // #4
        int i = countUntil!(d => d == important_d)(info.doos); // #5

        if (i>=0)  {  // assuming -1 represents value not found
             ... do stuff with i ...
        }
      }
      ...
    }

All the lines shown give me

    "template ... cannot deduce function from argument types..."

but one time I got, but cannot reproduce now, the error
    "Error: template instance countUntil!((d) => d == important_d, doos) has no value"

December 31, 2019
On Tuesday, 31 December 2019 at 04:38:53 UTC, Daren Scot Wilson wrote:
>  I'm needing to see more examples.  It might have something to do with the array I'm working with being inside a foreach loop. My code looks like this, with the problematic line duplicated to show some of the variations I tried:
>
>     import std.algorithm;
>
>     alias doo = ubyte;
>     struct Info
>     {
>         int x;
>         doo[NDOOS] doos;   // NDOOS = 10
>     }
>
>     immutable int INFO = 100000;
>     Info[NINFOS]  infos;    // global array, used heavily.
>
>     float foo_function(doo important_d)    {
>       ...
>       foreach (info; infos)    {
>
>         int i = info.doos.index(important_d);                  // #1
>         int i = info.doos.countUntil(d => d == important_d);   // #2
>         int i = info.doos.countUntil!(d => d == important_d);  // #3
>         int i = countUntil(d => d == important_d, info.doos);  // #4
>         int i = countUntil!(d => d == important_d)(info.doos); // #5
>
>         if (i>=0)  {  // assuming -1 represents value not found
>              ... do stuff with i ...
>         }
>       }
>       ...
>     }
>
> All the lines shown give me
>
>     "template ... cannot deduce function from argument types..."
>
> but one time I got, but cannot reproduce now, the error
>     "Error: template instance countUntil!((d) => d == important_d, doos) has no value"

countUntil operates on ranges, and static arrays aren't ranges. To get a range from a static array, you have to slice it with the `[]` operator:

    int i = info.doos[].countUntil(important_d);

(Why can't static arrays be ranges? Because ranges can shrink, via popFront, but a static array can never change its length.)
December 31, 2019
On Monday, 30 December 2019 at 23:15:48 UTC, JN wrote:
> I also had to ask because I couldn't find it. In other languages it's named "index()", "indexOf()" or "find()". D is the only language I know which uses the "countUntil" scheme. And even so it's not obvious from the name if it's the index of the element or number of preceding elements.

The main difference to other languages is that countUntil works an arbitrary ForwardRanges which might not offer random access, hence index would be misleading for them.

But improvements to the documentation could probably help to alleviate this confusion.
December 31, 2019
On Tuesday, 31 December 2019 at 04:38:53 UTC, Daren Scot Wilson wrote:
> On Monday, 30 December 2019 at 23:15:48 UTC, JN wrote:
>> On Sunday, 29 December 2019 at 08:31:13 UTC, mipri wrote:
>>>
>>> int i = a.countUntil!(v => v == 55);
>>> assert(i == 2);
>>
>> I also had to ask because I couldn't find it. In other languages it's named "index()", "indexOf()" or "find()". D is the only language I know which uses the "countUntil" scheme. And even so it's not obvious from the name if it's the index of the element or number of preceding elements.
>
>
> I had first tried myarray.index(myvalue) because I coulda sworn I wrote exactly that syntax a only a few days ago.  But I've been hopping between languages, some D, some Crystal, some C++, some Javascript, and with only two cerebral hemispheres, maybe I got confused. So, D doesn't have index()?  Is it called find()?  Something else?  It was hard to find the right stuff in the documentation.

You may have used indexOf, which works with strings. Why not anything else? No idea, as it really should work with other arguments.
December 31, 2019
On 12/30/19 6:15 PM, JN wrote:
> On Sunday, 29 December 2019 at 08:31:13 UTC, mipri wrote:
>>
>> int i = a.countUntil!(v => v == 55);
>> assert(i == 2);
> 
> I also had to ask because I couldn't find it. In other languages it's named "index()", "indexOf()" or "find()". D is the only language I know which uses the "countUntil" scheme. And even so it's not obvious from the name if it's the index of the element or number of preceding elements.
> 

indexOf used to be in std.algorithm I believe. It was nixed for having too simple an implementation I believe.

I have also created a bufref library [1] which is intended to help with using phobos algorithms and not losing the positional information.

import std.stdio;
import std.algorithm;
import bufref;

void main()
{
    string x = "hello, world!";
    writeln(x.bwin.find('o').bufRef.pos);
}

-Steve

[1] http://code.dlang.org/packages/bufref