Functional programming functions using 2 lists in D - functional-programming

If I have 2 lists:
list1 = [1, 2, 3, 4];
list2 = [10, 25, 35, 58];
and I want to get a list which has products of corresponding elements of 2 lists;
In Python one can do:
outlist = list(map(lambda a,b: a*b, list1, list2))
However, in D, I know of following method:
import std.stdio;
void main(){
auto list1 = [1, 2, 3, 4];
auto list2 = [10, 25, 35, 58];
int[] outlist;
foreach(i, item; list1){
outlist ~= item*list2[i];
}
writeln(outlist);
}
My questions are:
Q1: Can one keep both lists as argument of foreach?
Q2: How to multiply corresponding elements of 2 lists using map function?
Thanks for your insight.

The key is to use zip to combine the elements of the two lists (or dynamic arrays as they are known in D) to a single array of tuples before applying map or foreach. The tuple elements can be accessed with a zero based index (i.e. a[0] and a[1] in this example).
import std.algorithm.iteration : map;
import std.range : zip;
import std.stdio : writeln;
void main() {
auto list1 = [1, 2, 3, 4];
auto list2 = [10, 25, 35, 58];
// Question #2
auto list3 = zip(list1, list2).map!(a => a[0] * a[1]);
writeln(list3);
// Question #1
typeof(list1) list4;
foreach(a; zip(list1, list2)) {
list4 ~= a[0] * a[1];
}
writeln(list4);
}
The code above prints twice:
[10, 50, 105, 232]
as expected.

Related

ndarray: Is there an effective way to swap 2 row/cols/etc. in different arrays?

Using ndarray with 2 Array structs, is there an effective way to swap 2 rows/cols/(slices along some axis)?
The title really sums up the question.
While different people might mean different things by "effective", a straightforward way is to assign the rows/columns to each other by means of a temporary. Here is an example for two rows (Playground):
let mut a = arr2(&[[1, 2, 3], [4, 5, 6]]);
let mut b = arr2(&[[7, 8, 9], [10, 11, 12], [13, 14, 15]]);
let mut a_row = a.slice_mut(s![1, ..]);
let mut b_row = b.slice_mut(s![2, ..]);
let tmp = a_row.to_owned();
a_row.assign(&b_row);
b_row.assign(&tmp);
println!("a = {:?}", a);
println!("b = {:?}", b);
Alternatively, you can use azip!() to swap elementwise and avoid creating a temporary array, or even par_azip! to parallelize the copying.

How do I infinitely repeat a sequence in Kotlin?

I want to infinitely repeat T elements in a Sequence<T>. This can't be done using kotlin.collections.asSequence. For example:
val intArray = intArrayOf(1, 2, 3)
val finiteIntSequence = intArray.asSequence()
val many = 10
finiteIntSequence.take(many).forEach(::print)
// 123
This is not what I want. I expected some kind of kotlin.collections.repeat function to exist, but there isn't, so I implemented one myself (e.g. for this IntArray):
var i = 0
val infiniteIntSequence = generateSequence { intArray[i++ % intArray.size] }
infiniteIntSequence.take(many).forEach(::print)
// 1231231231
This is quite imperative, so I feel there must be a more functional and less verbose way to do this. If it exists, what is/are Kotlin's standard way(s) to repeat collections / arrays a(n) (in)finite amount of times?
Update: coroutines are no longer experimental as of Kotlin 1.3! Use them as much as you like :)
If you allow the use of coroutines you can do this in a pretty clean way using sequence:
an infinite amount of times
fun <T> Sequence<T>.repeat() = sequence { while (true) yieldAll(this#repeat) }
Note the use of a qualified this expression this#repeat - simply using this would refer to the lambda's receiver, a SequenceScope.
then you can do
val intArray = intArrayOf(1, 2, 3)
val finiteIntSequence = intArray.asSequence()
val infiniteIntSequence = finiteIntSequence.repeat()
println(infiniteIntSequence.take(10).toList())
// ^ [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]
a finite amount of times
fun <T> Sequence<T>.repeat(n: Int) = sequence { repeat(n) { yieldAll(this#repeat) } }
To avoid using the experimental coroutines, use:
generateSequence { setOf("foo", 'b', 'a', 'r') }
.flatten() // Put the Iterables' contents into one Sequence
.take(5) // Take 5 elements
.joinToString(", ")
// Result: "foo, b, a, r, foo"
or alternatively, if you want to repeat the entire collection a number of times, just take before flattening:
generateSequence { setOf("foo", 'b', 'a', 'r') }
.take(5) // Take the entire Iterable 5 times
.flatten() // Put the Iterables' contents into one Sequence
.joinToString(", ")
// Result: "foo, b, a, r, foo, b, a, r, foo, b, a, r, foo, b, a, r, foo, b, a, r"
For the original question's IntArray, the array first must be converted to an Iterable<Int> (otherwise flatten() isn't available):
val intArray = intArrayOf(1, 2, 3)
generateSequence { intArray.asIterable() }
.flatten()
.take(10)
.joinToString(", ")
// Result: "1, 2, 3, 1, 2, 3, 1, 2, 3, 1"
Furthermore, other types of Array, e.g. ByteArray or LongArray, as well as Map are not Iterable, but they all implement the asIterable() method like IntArray in the example above.
I think this is pretty clear:
generateSequence(0) { (it + 1) % intArray.size }
.map { intArray[it] }
.forEach { println(it) }
A generic solution would be to reuse the proposal from this answer with extension functions:
fun <T> Array<T>.asRepeatedSequence() =
generateSequence(0) {
(it + 1) % this.size
}.map(::get)
fun <T> List<T>.asRepeatedSequence() =
generateSequence(0) {
(it + 1) % this.size
}.map(::get)
Called like this:
intArray.asRepeatedSequence().forEach(::println)
I'm unsure if this is due to API changes in Kotlin, but it's possible to do the following:
fun <T> Sequence<T>.repeatForever() =
generateSequence(this) { it }.flatten()
Live example: https://pl.kotl.in/W-h1dnCFx
If you happen to have Guava on your classpath, you can do the following:
val intArray = intArrayOf(1, 2, 3)
val cyclingSequence = Iterators.cycle(intArray.asList()).asSequence()
// prints 1,2,3,1,2,3,1,2,3,1
println(cyclingSequence.take(10).joinToString(","))

Lazily grouping a flat sequence in F#

Given a sequence of items as follows:
[ ("a", 1); ("a", 2); ("a", 3); ("b", 1); ("c", 2); ("c", 3) ]
How can I convert this lazily into:
{ ("a", { 1; 2; 3}); ("b", { 1 }); ("c", { 2; 3}) }
You can assume that the input data source is already sorted on the grouping key element e.g. "a" "b" and "c".
I'm using the { } there to indicate that it's a lazily-evaluated sequence of items.
I've gotten it working imperatively with two while loops operating over the IEnumerator of the source sequence, but this involves creating reference variables and mutation etc. etc. I'm sure that there are better ways of doing this, perhaps with Recursion or using some of the operations in the Seq library e.g. scan or unfold?
If you want to implement this over IEnumerable<'T> (to make it lazy), then it is necessarily going to be somewhat imperative, because the IEnumerator<'T> type that is used to iterate over the input is imperative. But the rest can be written as a recursive function using sequence expressions.
The following is lazy in the first level (it produces each group lazily), but it does not produce elements of the group lazily (I think that would have pretty subtle semantics):
/// Group adjacent elements of 'input' according to the
/// keys produced by the key selector function 'f'
let groupAdjacent f (input:seq<_>) = seq {
use en = input.GetEnumerator()
// Iterate over elements and keep the key of the current group
// together with all the elements belonging to the group so far
let rec loop key acc = seq {
if en.MoveNext() then
let nkey = f en.Current
if nkey = key then
// If the key matches, append to the group so far
yield! loop key (en.Current::acc)
else
// Otherwise, produce the group collected so far & start a new one
yield List.rev acc
yield! loop nkey [en.Current]
else
// At the end of the sequence, produce the last group
yield List.rev acc
}
// Start with the first key & first value as the accumulator
if en.MoveNext() then
yield! loop (f en.Current) [en.Current] }
Unfortunately, this (pretty useful!) function is not included in the standard F# library, so if you want to group adjacent elements (rather than arbitrary elements in the list using Seq.groupBy), you have to define it yourself...
let p = [("a", 1); ("a", 2); ("a", 3); ("b", 1); ("c", 2); ("c", 3)]
let l = p |> Seq.groupBy fst |> Seq.map(fun x -> fst x, snd x |> Seq.map snd)
In F#+ there is a generic function chunkBy that can be used to do that:
#r "FSharpPlus.dll"
open FSharpPlus
seq [ ("a", 1); ("a", 2); ("a", 3); ("b", 1); ("c", 2); ("c", 3) ]
|> chunkBy fst
|> map (fun (x,y) -> x, map snd y)
And it works with seq, array and list.
The implementation for seq is pretty much the same as the groupdAdjacent from Tomas.
Seq.groupBy fst
Will do the trick

Converting java.util.List into a JavaFX sequence

What is the most concise way of converting a java.util.List into a normal
JavaFX sequence (in JavaFX)?
e.g.
def myList = java.util.Arrays.asList(1, 2, 3);
def mySequence = ... // a sequence containing [1, 2, 3]
This is the most concise way I could find - there may be a more direct method though
def myList = java.util.Arrays.asList(1, 2, 3);
def mySequence = for (i in myList) i;
println("mySequence={mySequence}");

JavaFX: concatenating sequences

Is there a standard library function or built-in construct to concatenate two sequences in JavaFX?
Here a Sequences.concatenate() function is mentioned, but it is nowhere to be seen in the official API.
Of course one could iterate over each sequence, inserting the values into a new sequence e.g:
function concatenate(seqA: Object[], seqB: Object[]) : Object[] {
for(b in seqB) insert b into seqA;
seqA;
}
..but surely something as basic as concatenation is already defined for us somewhere..
It is very simple, since there cannot be sequence in sequence (it all gets flattened), you can do it like this:
var a = [1, 2];
var b = [3, 4];
// just insert one into another
insert b into a;
// a == [1, 2, 3, 4];
// or create a new seq
a = [b, a];
// a == [3, 4, 1, 2];
Hope that helps.

Resources