Range with step in Ramda - ramda.js

What's the best way to do the following in Ramda:
_.range(0, 3, 0);
// => [0, 0, 0]
Thank you.

If you need to repeat the same number n times, then Ori Drori already provided a good answer with repeat.
However if you need to support step, you would have to build a function yourself. (Ramda has a range function but it does not support step.)
So where Lodash would return:
_.range(1, 10, 2);
//=> [1, 3, 5, 7, 9]
You can achieve a similar functionality with Ramda unfold function:
const rangeStep = curry((start, end, step) =>
unfold(n => n < end ? [n, n + step] : false, start));
rangeStep(1, 10, 2);
//=> [1, 3, 5, 7, 9]

You can use R.repeat to create an array of multiple instances of a single item:
const result = R.repeat(0, 3)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

Related

Search predecessors only upto a certain node in cytoscape.js

I can use the predecessors function to find all the predecessors of a node. What I want is to find a predecessor upto a certain.
(The graph is constrained to have that one parent)
Example:
In the above picture, if I call predecessors on node 8, it would give me [1, 2, 3, 4, 5, 6, 7] as the result (ignoring edges).
I want it to limit the search only upto a certain node. If I want it to limit the search until 4, it should return only [4, 5, 6, 7]. Not anything above it.
Is it possible using native cytoscape functions?
The predecessors function accepts selectors and I've tried using that like node.predecessors("node#4 node") according to the docs. But it returned nothing.
I managed to solve it by finding all the successors of the node I'm trying to stop at, then intersecting it with the predecessors of the input node:
const node = cy.$('node#8');
const predecessors = node.predecessors(); // [1, 2, 3, 4, 5, 6, 7]
const requiredRootNode = cy.$('node#4');
const rootChildren = requiredRootNode.successors(); // [5, 6, 7, 8]
const intersection = rootChildren.intersection(predecessors); // [5, 6, 7]
const result = intersection.add(requiredRootNode); // [4, 5, 6, 7]
You can use either use depthFirstSearch or breadthFirstSearch.
The code sample there would allow you to change the visit. Change the following to your liking:
const limitingID = '4';
var bfs = cy.elements().bfs({
roots: '#e',
visit: function(v){
// Stopping at desired node
if( v.id == limitingID ){
return true;
}
},
directed: false
});
var path = bfs.path; // path to found node
var found = bfs.found; // found node

numpy append in a for loop with different sizes

I have a for loop but where i has changes by 2 and i want to save a value in a numpy array in each iteration that that changes by 1.
n = 8 #steps
# random sequence
rand_seq = np.zeros(n-1)
for i in range(0, (n-1)*2, 2):
curr_state= i+3
I want to get curr_state outside the loop in the rand_seq array (seven values).
can you help me with that?
thanks a lot
A much simpler version (if I understand the question correctly) would be:
np.arange(3, 15+1, 2)
where 3 = start, 15 = stop, 2 = step size.
In general, when using numpy try to avoid adding elements in a for loop as this is inefficient. I would suggest checking out the documentation of np.arange(), np.array() and np.zeros() as in my experience, these will solve 90% of array - creation issues.
A straight forward list iteration:
In [313]: alist = []
...: for i in range(0,(8-1)*2,2):
...: alist.append(i+3)
...:
In [314]: alist
Out[314]: [3, 5, 7, 9, 11, 13, 15]
or cast as a list comprehension:
In [315]: [i+3 for i in range(0,(8-1)*2,2)]
Out[315]: [3, 5, 7, 9, 11, 13, 15]
Or if you make an array with the same range parameters:
In [316]: arr = np.arange(0,(8-1)*2,2)
In [317]: arr
Out[317]: array([ 0, 2, 4, 6, 8, 10, 12])
you can add the 3 with one simple expression:
In [318]: arr + 3
Out[318]: array([ 3, 5, 7, 9, 11, 13, 15])
With lists, iteration and comprehensions are great. With numpy you should try to make an array, such as with arange, and modify that with whole-array methods (not with iterations).

Is there an inverse of _.groupBy?

I am using lodash and have grouped an array of objects on a key that they shared; I then do calculations to these objects in these groups but now I need to ungroup.
Is there any way to do this in lodash?
Thanks
You can use _.flatMap() to "ungroup", but it won't restore the original order:
const arr = [2, 3, 4, 2, 3, 4]
const grouped = _.groupBy(arr)
console.log(JSON.stringify(grouped))
const ungrouped = _.flatMap(grouped)
console.log(JSON.stringify(ungrouped))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Divide list into parts

Is there a simple way to divide list into parts (maybe some lambda) in Kotlin?
For example:
[1, 2, 3, 4, 5, 6] => [[1, 2], [3, 4], [5, 6]]
Since Kotlin 1.2 you can use Iterable<T>.chunked(size: Int): List<List<T>> function from stdlib (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/chunked.html).
Given the list: val list = listOf(1, 2, 3, 4, 5, 6) you can use groupBy:
list.groupBy { (it + 1) / 2 }.map { it.value }
Or if your values are not numbers you can first assign an index to them:
list.withIndex()
.groupBy { it.index / 2 }
.map { it.value.map { it.value } }
Or if you'd like to save some allocations you can go a bit more manual way with foldIndexed:
list.foldIndexed(ArrayList<ArrayList<Int>>(list.size / 2)) { index, acc, item ->
if (index % 2 == 0) {
acc.add(ArrayList(2))
}
acc.last().add(item)
acc
}
The better answer is actually the one authored by VasyaFromRussia.
If you use groupBy, you will have to add and index and then post-process extracting the value from an IndexedValue object.
If you use chunked, you simply need to write:
val list = listOf(10, 2, 3, 4, 5, 6)
val chunked = list.chunked(2)
println(chunked)
This prints out:
[[10, 2], [3, 4], [5, 6]]
Nice way of dividing list is by the use of function partition. Unlike groupBy it doesn't divide list by keys but rather by predicate which gives out Pair<List, List> as a result.
Here's an example:
val (favorited, rest) = posts.partition { post ->
post.isFavorited()
}
favoritedList.addAll(favorited)
postsList.addAll(rest)
The API says there is a GroupBy function, which should do what you want.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/group-by.html
Or use sublist and break it up yourself
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/sub-list.html
If you want to divide a list into N parts.
(and not divide a list into parts of size N)
You can still use the chunked answer:
https://stackoverflow.com/a/48400664/413127
Only, first you need to find your chunk size.
val parts = 2
val list = listOf(10, 2, 3, 4, 5, 6)
val remainder = list.size % 2 // 1 or 0
val chunkSize = (list.size / parts) + remainder
val chunked = list.chunked(chunkSize)
println(chunked)
This prints out
[[10, 2, 3], [4, 5, 6]]
or when
val parts = 3
This prints out
[[10, 2], [3, 4], [5, 6]]
Interesting answer in Python here: Splitting a list into N parts of approximately equal length

Delete rows from a ndarray in python

I have a 2D - array A, which contains the x and y coordinates of points
array([[ 0, 0],
[ 0, 0],
[ 0, 0],
[ 3, 4],
[ 4, 1],
[ 5, 10],
[ 9, 7]])
as you can see the point ( 0 , 0 ) appears more often.
I want to delete this point so that the array looks like this:
array([[ 3, 4],
[ 4, 1],
[ 5, 10],
[ 9, 7]])
Since the array in real is very huge, it is very important to do this without for loops, otherwise it takes very long.
I'm new to python but i'm used to matlab, where I can solve it very easily with:
A (A(:,1) == 0 & A(:,2) == 0, :) = []
I thought it is almost the same or very similar in python, but I can't figure it out - am totally stuck. Errors like "use a.any()/all()" or "ufunc "bitwise_and" not supported for the input types" appear and I don't know what I should change.
Technically what you are doing in MATLAB is not deleting elements from A. What you are actually doing is creating a new array that lacks the elements of A. It is equivalent to:
>> A = A (A(:,1) ~= 0 | A(:,2) ~= 0, :);
You can do exactly the same thing in numpy:
>>> a = a[(a[:,0] != 0) | (a[:,1] != 0), :]
However, thanks to numpy's automatic broadcasting, you can make this simpler:
>>> a = a[(a != [0, 0]).any(1)]
This will work for any target array so long as it has the same number of columns as a.