ramda merging 2 json objects depending on there types - ramda.js

I need to merge 2 json object when the values are arrays there contents should be concatenated and if the values are primitive type then the value of first object should be taken.
R.mergeDeepWith(R.concat,
{ a: true, c: { values: [10, 20], d: { names: ['Alex']} }},
{ a: false, b: true, c: { values: [15, 35] , d: { address: ['Diesel Str 2']}}});
Arrays or deep object are working but for the key a I am getting an error.

I would probably do something like this:
const myMerge = mergeDeepWith(
(a, b) => is (Array) (a) && is (Array) (b) ? concat (a, b) : a)
console .log (myMerge (
{a: true, c: {values: [10, 20]}},
{a: false, b: true, c: {values: [15, 35]}}
))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script>const {mergeDeepWith, is, concat} = R</script>
We use mergeDeepWith and then call concat if both arguments are arrays, choosing the first one if not.

Related

How to .each_char.map?

In Crystal, if I try this:
numbers = [1, 2, 3, 4, 5]
a = numbers.map { 0 }
p a
The output will be nice like this: [0, 0, 0, 0, 0]
However if I have a string and try to manipulate each char of that string individually with each_char it gets messier
word = "NUMBER"
b = word.each_char.map { 'x' }
p b
The output will be like this:
Iterator::Map(String::CharIterator, Char, Char)(#iterator=#<String::CharIterator:0x7f0040951f50 #reader=Char::Reader(#string="NUMBER", #current_char='N', #current_char_width=1, #pos=0, #error=nil, #end=false), #end=false>, #func=#<Proc(Char, Char):0x453190>)
In contrast, Ruby with the same code outputs:
["x", "x", "x", "x", "x", "x"]
Is there a way to do this to get the same or similar output as Ruby gives in Crystal?
You can collect the iterator's elements into an array using Iterator#to_a, which it inherits from Enumerable:
p "NUMBER".each_char.map { 'x' }.to_a # => ['x', 'x', 'x', 'x', 'x', 'x']
Alternatively you can start out with an array by using String#chars and then calling Array#map on it:
p "NUMBER".chars.map { 'x' } # => ['x', 'x', 'x', 'x', 'x', 'x']
This pattern of each_foo returning an Iterator and foos returning an Array can be found throughout most of the standard library.

how to print out a table in nextflow

I am starting out with Nextflow and can't seem to figure out why my script isn't doing what I'm expecting
import nextflow.Channel
params.groupings = "SampleGroups.csv"
params.comparisons = "comparisons.tsv"
groupings = params.groupings
comp = params.comparisons
println groupings.class
def parseGroupings(groupings){
def allRows = [:]
Channel.from(groupings)
.splitCsv(sep: ',', header: true)
.unique().map { row ->
[row.Sample,row.Group]
}
}
(a,b) = parseGroupings(groupings).into(2)
println a.flatten().unique().toSortedList().get()
I am expecting it to print the rows of the groupings file I put in but instead I get:
class java.lang.String
[]
The array is empty, but my file is clearly not. What's the easiest way to check the contents of my output and "see" what I'm doing?
Use .view() to inspect a channel's content and return a copy of that channel.
Channel.from(1,2,3).view()
.map { it -> [it, it+it, it*it] }
.view()
.set { foo }
foo.collect().view()
output:
1
2
3
[1, 2, 1]
[2, 4, 4]
[3, 6, 9]
[1, 2, 1, 2, 4, 4, 3, 6, 9]

What does a prefixed asterisk mean

I came across the following Kotlin code:
single(name = walletOkHttpTag) {
createOkHttpClient {
addHeaders(
*mutableListOf<Pair<String, String>>().apply {
add(HeaderKey.ACCEPT to APPLICATION_JSON_HEADER)
if (isDebug || isBeta) {
add(HeaderKey.AUTHORIZATION to BASIC_AUTH_WALLET_STAGE_HEADER)
}
}.toTypedArray()
)
}
}
What does the asterisk * mean that is in front of mutableListOf?
This is the spread operator and it is required to pass an existing array to a vararg function.
When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *):
Simplified example from the documentation:
val a = arrayOf(1, 2, 3)
val list = listOf(-1, 0, *a, 4)
println(list)
Output:
[-1, 0, 1, 2, 3, 4]
Without the spread operator, the array itself would be added as a single element, resulting in a List<Serializable> with 4 elements:
[-1, 0, [Ljava.lang.Integer;#31befd9f, 4]

What is the equivalent of Python list, set, and map comprehensions in Kotlin?

In Python, there are list comprehensions and similar constructs for maps and sets. In Kotlin there is nothing at all in any of the documentation with a similar name.
What are the equivalents of these comprehensions? For example, those found in Python 3 Patterns, Recipes and Idioms. Which includes comprehensions for:
list
set
dictionary
Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that the idiomatic answers to commonly asked Kotlin topics are present in SO.
Taking examples from Python 3 Patterns, Recipes and Idioms we can convert each one to Kotlin using a simple pattern. The Python version of a list comprehension has 3 parts:
output expression
input list/sequence and variable
optional predicate
These directly correlate to Kotlin functional extensions to collection classes. The input sequence, followed by the optional predicate in a filter lambda, followed by the output expression in a map lambda. So for this Python example:
# === PYTHON
a_list = [1, 2, 3, 4, 5, 6]
# output | var | input | filter/predicate
even_ints_squared = [ e*e for e in a_list if e % 2 == 0 ]
print(even_ints_squared)
# output: [ 4, 16, 36 ]
Becomes
// === KOTLIN
var aList = listOf(1, 2, 3, 4, 5, 6)
// input | filter | output
val evenIntsSquared = aList.filter { it % 2 == 0 }.map { it * it }
println(evenIntsSquared)
// output: [ 4, 16, 36 ]
Notice that the variable is not needed in the Kotlin version since the implied it variable is used within each lambda. In Python you can turn these into a lazy generator by using the () instead of square brackets:
# === PYTHON
even_ints_squared = ( e**2 for e in a_list if e % 2 == 0 )
And in Kotlin it is more obviously converted to a lazy sequence by changing the input via a function call asSequence():
// === KOTLIN
val evenIntsSquared = aList.asSequence().filter { it % 2 == 0 }.map { it * it }
Nested comprehensions in Kotlin are created by just nesting one within the other's map lambda. For example, take this sample from PythonCourse.eu in Python changed slightly to use both a set and a list comprehension:
# === PYTHON
noprimes = {j for i in range(2, 8) for j in range(i*2, 100, i)}
primes = [x for x in range(2, 100) if x not in noprimes]
print(primes)
# output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Becomes:
// === KOTLIN
val nonprimes = (2..7).flatMap { (it*2..99).step(it).toList() }.toSet()
val primes = (2..99).filterNot { it in nonprimes }
print(primes)
// output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Notice that the nested comprehension produces a list of lists which is converted to a flat list using flatMap() and then converted to a set using toSet(). Also, Kotlin ranges are inclusive, whereas a Python range is exclusive so you will see the numbers are slightly different in the ranges.
You can also use a sequence generator with co-routines in Kotlin to yield the values without needing the call to flatMap() or flatten():
// === KOTLIN
val nonprimes = sequence {
(2..7).forEach { (it*2..99).step(it).forEach { value -> yield(value) } }
}.toSet()
val primes = (2..99).filterNot { it in nonprimes }
Another example from the referenced Python page is generating a matrix:
# === PYTHON
matrix = [ [ 1 if item_idx == row_idx else 0 for item_idx in range(0, 3) ] for row_idx in range(0, 3) ]
print(matrix)
# [[1, 0, 0],
# [0, 1, 0],
# [0, 0, 1]]
And in Kotlin:
// === KOTLIN
val matrix = (0..2).map { row -> (0..2).map { col -> if (col == row) 1 else 0 }}
println(matrix)
// [[1, 0, 0],
// [0, 1, 0],
// [0, 0, 1]]
Or in Kotlin instead of lists, you could also generate arrays:
// === KOTLIN
val matrix2 = Array(3) { row ->
IntArray(3) { col -> if (col == row) 1 else 0 }
}
Another of the examples for set comprehensions is to generate a unique set of properly cased names:
# === PYTHON
names = [ 'Bob', 'JOHN', 'alice', 'bob', 'ALICE', 'J', 'Bob' ]
fixedNames = { name[0].upper() + name[1:].lower() for name in names if len(name) > 1 }
print(fixedNames)
# output: {'Bob', 'Alice', 'John'}
Is translated to Kotlin:
// === KOTLIN
val names = listOf( "Bob", "JOHN", "alice", "bob", "ALICE", "J", "Bob" )
val fixedNames = names.filter { it.length > 1 }
.map { it.take(1).toUpperCase() + it.drop(1).toLowerCase() }
.toSet()
println(fixedNames)
// output: [Bob, John, Alice]
And the example for map comprehension is a bit odd, but can also be implemented in Kotlin. The original:
# === PYTHON
mcase = {'a':10, 'b': 34, 'A': 7, 'Z':3}
mcase_frequency = { k.lower() : mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys() }
print(mcase_frequency)
# output: {'a': 17, 'z': 3, 'b': 34}
And the converted, which is written to be a bit more "wordy" here to make it clearer what is happening:
// === KOTLIN
val mcase = mapOf("a" to 10, "b" to 34, "A" to 7, "Z" to 3)
val mcaseFrequency = mcase.map { (key, _) ->
val newKey = key.toLowerCase()
val newValue = mcase.getOrDefault(key.toLowerCase(), 0) +
mcase.getOrDefault(key.toUpperCase(), 0)
newKey to newValue
}.toMap()
print(mcaseFrequency)
// output: {a=17, b=34, z=3}
Further reading:
Kotlin adds more power than list/set/map comprehensions because of its extensive functional transforms that you can make to these collection types. See What Java 8 Stream.collect equivalents are available in the standard Kotlin library?
for more examples.
See Get Factors of Numbers in Kotlin
which shows another example of a Python comprehension versus Kotlin.
See Kotlin Extensions Functions for Collections in the API reference guide.
Just for exercise the closest to python will be:
infix fun <I, O> ((I) -> O).`in`(range: Iterable<I>): List<O> = range.map(this).toList()
infix fun <I> Iterable<I>.`if`(cond: (I) -> Boolean): List<I> = this.filter(cond)
fun main() {
{ it: Int -> it + 1 } `in` 1..2 `if` {it > 0}
}
val newls = (1..100).filter({it % 7 == 0})
in Kotlin is equivalent to the following Python code
newls = [i for i in 0..100 if i % 7 ==0]
Map comprehension
import kotlin.math.sqrt
val numbers = "1,2,3,4".split(",")
val roots = numbers.associate { n -> n.toInt() to sqrt(n.toFloat()) }
println(roots) // prints {1=1.0, 2=1.4142135, 3=1.7320508, 4=2.0}
If keys are untransformed elements of source list, even simpler:
val roots = numbers.associateWith { n -> sqrt(n.toFloat()) }

Use Lodash's reduce to sum a collection

I have a simple collection:
[{a: 1}, {a: 2}, {a: 3}]
How do I use Lodash's reduce to get the sum of all "a" attributes?
This seems like a trivial / canonical use, but I can't get the syntax right and surprisingly can't find any docs beyond Lodash's example.
Using Lodash's docs example, it should be:
const total = _.reduce([{ a: 1}, {a: 2}, {a: 3}], (sum, elem) => elem.a);
However this returns the value "3" instead of "6'.
Note: I'm specifically asking about the usage of reduce. I'm aware of other methods like the one in this question.
You're forgetting to add sum to elem.a. Also, you need an initial reduction, otherwise, sum will be initialized to { a: 1 }:
_.reduce([{ a: 1}, {a: 2}, {a: 3}], (sum, elem) => sum + elem.a, 0);
You might want to look at sumBy() for this too. It's the same reducer, only more concise:
_.sumBy([{ a: 1}, {a: 2}, {a: 3}], 'a');