Hi all,
A little advice please. Using D v1.028.
I have (currently) an array of uints. I need to output these sorted, which
.sort does admirably,
but I need to know what index is associated with each value. How?
Springing from my own use of the word "associated", I thought that maybe I
should be using
and associative array for this. But again the problem is that I would need to
sort the keys
by their associated values.
In Perl I'd do
my array = ...;
## Get the indexes ordered by their values
my orderIndexes = sort{
$array[ $a ] <=> $array[ $b ]
} 0 .. $#array;
for my $i ( orderedIndexes ) {
printf "%d : %d\n2, $i, $array[ $i ];
}
Is there anything built-in or in Phobos that will help me here?
Or do I need to write my own sort?
Cheers, b.
--
On Sun, 4 May 2008 07:58:16 +0000 (UTC), Me Here wrote:
Hi all,
A little advice please. Using D v1.028.
I have (currently) an array of uints. I need to output these sorted, which
.sort does admirably,
but I need to know what index is associated with each value. How?
Springing from my own use of the word "associated", I thought that maybe I
should be using
and associative array for this. But again the problem is that I would need to
sort the keys
by their associated values.
In Perl I'd do
my array = ...;
## Get the indexes ordered by their values
my orderIndexes = sort{
$array[ $a ] <=> $array[ $b ]
} 0 .. $#array;
for my $i ( orderedIndexes ) {
printf "%d : %d\n2, $i, $array[ $i ];
}
Is there anything built-in or in Phobos that will help me here?
Or do I need to write my own sort?
Cheers, b.
On Sun, 4 May 2008 07:58:16 +0000 (UTC), Me Here wrote:
Hi all,
A little advice please. Using D v1.028.
I have (currently) an array of uints. I need to output these sorted, which
.sort does admirably,
but I need to know what index is associated with each value. How?
Springing from my own use of the word "associated", I thought that maybe I
should be using
and associative array for this. But again the problem is that I would need
to sort the keys
by their associated values.
In Perl I'd do
my array = ...;
## Get the indexes ordered by their values
my orderIndexes = sort{
$array[ $a ] <=> $array[ $b ]
} 0 .. $#array;
for my $i ( orderedIndexes ) {
printf "%d : %d\n2, $i, $array[ $i ];
}
Is there anything built-in or in Phobos that will help me here?
Or do I need to write my own sort?
Cheers, b.
On Sun, 4 May 2008 13:11:23 +0000 (UTC), Me Here wrote:
I need them ordered by the values not the keys.
Eg. Given, (whether array or hash):
//index/key 0 1 2 3 4 5 6 7 8
uint a[] = [ 3, 1, 8, 6, 4, 9, 2, 5, 7 ];
I need to output:
// value - index
1 - 1
2 - 6
3 = 0
4 - 4
5 - 7
6 - 3
7 - 8
8 - 2
9 - 5
The trick I use for this is to have two AAs. When the set is small,
performance isn't really an issue.
import std.stdio;
void main()
{
int[int] theArray;
theArray[0] = 3;
theArray[1] = 1;
theArray[2] = 8;
theArray[3] = 6;
theArray[4] = 4;
theArray[5] = 9;
theArray[6] = 2;
theArray[7] = 5;
theArray[8] = 7;
int[int] altArray;
foreach(int i; theArray.keys)
{
altArray[ theArray[i] ] = i;
}
foreach(int i; altArray.keys.sort)
writefln("%s - %s", i, altArray[i]);
}
Problem: That works fine if the values in the origianl array are unique.
But in this case thay are not. This is frequency information.
The index to the array is numeric value of words in a file.
The values are counts of the occurance of that value in the file,
A truncated sample showing the first of many duplicates.
0 : 5780646
1 : 219016
2 : 138623
3 : 100037
4 : 89876
5 : 61845
6 : 60890
7 : 41191
8 : 60231
9 : 36885 *
...
70 : 13069
71 : 36885 *
72 : 16121
73 : 10721
I need to out put this as either:
...
36885: 9, 70
...
or
36885: 9
36885: 70
Cheers, b.
--
Problem: That works fine if the values in the origianl array are unique.
But in this case thay are not. This is frequency information.
The index to the array is numeric value of words in a file.
The values are counts of the occurance of that value in the file,
A truncated sample showing the first of many duplicates.
0 : 5780646
1 : 219016
2 : 138623
3 : 100037
4 : 89876
5 : 61845
6 : 60890
7 : 41191
8 : 60231
9 : 36885 *
...
70 : 13069
71 : 36885 *
72 : 16121
73 : 10721
I need to out put this as either:
...
36885: 9, 70
...
or
36885: 9
36885: 70
Cheers, b.
I suggest you write your own sort function which will sort two arrays
accordingly. Shell sort would probably be the easiest to implement this for.
May 04 2008
↑↓←→ Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Me Here wrote:
Problem: That works fine if the values in the origianl array are unique.
But in this case thay are not. This is frequency information.
The index to the array is numeric value of words in a file.
The values are counts of the occurance of that value in the file,
Try putting them in an array of structs with overloaded opCmp, and then
sorting that. For example:
-----
module test;
import tango.io.Stdout;
import tango.text.convert.Format;
struct Pair {
int a, b;
int opCmp(Pair* other) {
if (a != other.a)
return typeid(typeof(a)).compare(&a, &other.a);
return typeid(typeof(b)).compare(&b, &other.b);
}
char[] toString() {
return Format("{}:{}", a, b);
}
}
void main() {
int[int] aa = [43: 2, 42: 12, 10: 3, 100: 1000, 101: 200, 7: 3];
Stdout(aa).newline;
auto arr = new Pair[aa.length];
size_t i = 0;
foreach (key, val ; aa)
arr[i++] = Pair(val, key);
arr.sort;
Stdout(arr).newline;
}
-----
output:
=====
{ 100=>1000, 101=>200, 7=>3, 10=>3, 42=>12, 43=>2 }
[ 2:43, 3:7, 3:10, 12:42, 200:101, 1000:100 ]
=====
Notes:
* Tango is only used for formatting and could easily be replaced by
appropriate Phobos routines.
* I used typeid().compare because simple subtraction might overflow for
integer data >= int.sizeof.
* You may want to use an unsigned type for the frequency. Just change
the types of the AA and the Pair member data. Optionally, template Pair
on the types if you need to do this for multiple data types.
On Sun, 4 May 2008 13:52:42 +0000 (UTC), Me Here wrote:
Derek Parnell wrote:
The trick I use for this is to have two AAs. When the set is small,
performance isn't really an issue.
Doh! Of course that's an issue. My bad ... just come off playing a couple
of hours of COD4 :-)
COD4 + programming... Is that anything like playing a few hours of GTA,
and then immediately driving to the corner store for a soda and some chips?
- Pragma
I have (currently) an array of uints. I need to output these sorted, which
.sort does admirably,
but I need to know what index is associated with each value. How?
I have (currently) an array of uints. I need to output these sorted, which
.sort does admirably,
but I need to know what index is associated with each value. How?
sortAA() looks like it would do the trick, but could you expand on the example
a litle for me. I'm sure the sub signature should tell me all I need to know,
but I'm having a problem working out how to call it?
--------
TyKey[] sortedAA(TyKey,TyVal,TyFun)(TyVal[TyKey] aa, TyFun key);
void valGetter();
Return the keys of an AA sorted according to the result of the given
function/delegate 'key' applied on two arguments, the key and value.
'key' can be any callable, or it can be the predefined &valGetter to sort the
AA keys according to the values.
Example:
Sort the keys of an AA according to the values:
int[string] a = ["DD":3, "aa":1, "BB":2];
sortedAA(d, &valGetter) ==> ["aa", "BB", "DD"]
If you use this to sort an AA according to values, using a valGetter function,
you are paying just about 5% speed penality.
Throws ArgumentException if key returns void.
----------------
If I define my hash as
uint freq[ ushort ];
How do I write valGetter() ?
Cheers, b.
--
Use the predefined one, my libs are supposed to minimize the work for the
programmer ;-)
Bye,
bearophile
Oh. I guess I was confused by the implementation:
void valGetter() { } /// ditto
I couldn't for the life of me se how that would work as is, so I assumed it
must be some kind of virtual functio or place holder.
Actually, I /still/ don't understand how it can work, but if you say it does I
will try it.
What the convention of where to place thrid-party libraries?
The stem (root, path; package?) of the librabry names 'd.*' seems um.. a little
generic?
Cheers, b.
--
Oh. I guess I was confused by the implementation:
void valGetter() { } /// ditto
I couldn't for the life of me se how that would work as is, so I assumed it
must be some kind of virtual functio or place holder.
Actually, I /still/ don't understand how it can work, but if you say it does I
will try it.
sortedAA() accepts any callable with key+val arguments, and sorts the keys of
the given AA according to the result of that callable, like the key attribute
of Python sort()/sorted().
If the callable is the default valGetter, then the result of that callable is
meant to be right the value. So it sorts according to the values. That's quite
similar to the itemgetter() and similar functions in the operator module of the
Python standard library.
If you try the given example, or you look inside the tens of unittests, you can
see how and why it works. It's just an empty function, used as flag, to
simplify the life of the user.
What the convention of where to place thrid-party libraries?
The stem (root, path; package?) of the librabry names 'd.*' seems um.. a little
generic?
The package is called "d". I know no other package with that name that may
collide with it. You can put that directory inside the directory of your
modules, libs, etc. Then you have to tell "bud" (or similar tool, there's
another more modern one, that I don't use) the path of that directory of your
modules.
Then at the top of your code you can use:
import d.func: sortAA;
And bud will find the right module and its dependent modules, and compile them.
If you need more compilation speed you can compile the d libs in a library
"lib" and maybe create "short" modules, all using the DMD compiler and its
tools.
Bye,
bearophile
Hi all,
A little advice please. Using D v1.028.
I have (currently) an array of uints. I need to output these sorted,
which
.sort does admirably,
but I need to know what index is associated with each value. How?
Springing from my own use of the word "associated", I thought that
maybe I
should be using
and associative array for this. But again the problem is that I would
need to
sort the keys
by their associated values.
In Perl I'd do
my array = ...;
## Get the indexes ordered by their values
my orderIndexes = sort{
$array[ $a ] <=> $array[ $b ]
} 0 .. $#array;
for my $i ( orderedIndexes ) {
printf "%d : %d\n2, $i, $array[ $i ];
}
Is there anything built-in or in Phobos that will help me here? Or do
I need to write my own sort?
Cheers, b.
pack it in ulongs with the index in the lower bits and the value in the upper
bits.
auto tmp = new ulong[](array.length)
foreach(uint i, uint v; array) tmp[i] = (cast(ulong)v)<<32 | i;
tmp.sort;
// get value of item i
cast(uint)(tmp[i]>>32);
// get index of item i;
cast(uint)(tmp[i] & 0xffff_ffff);
This isn't the first time a request for the permutation computed by the
sort routine comes up. Should such be incorprated into the language?
method
that was called back with both the [index, value] or [key,value] of the items
being
compared and returning -1, 0, +1, would allow for custom sorting.
The other notion that crossed my mind was having the ability to locally (scoped)
override the opCmp of built-in types, but that would require all opCmps to
expect two pairs.
b.
--