How to copy list of values from one array to another array on some interval using Rxjs? - rxjs5

Using Rxjs, I need to copy 10 next values evey 200ms from arr1 to arr2. I come up with below code, but there should be some Rxjs way to do.
originalArr= [];
newArr = [];
Rx.Observable.interval(200)
.scan((acc, val) => acc + 10)
.takeWhile(v => v < this.value.length)
.subscribe(val => {
const arr = this.value.slice(val, val+10);
arr.forEach(v => this.newVal.push(v));
});

Related

What does it mean to put a function into 'setState()' parameter in React-hook method?

First of all, please understand that I'm not good at English.
I am studying react-hook.
I am looking at an example code, and the factors(?) is declared in the function component as follows.
const lottoNumbers = useMemo(() => getWinNumbers(), []);
const [winNumbers, setWinNumbers] = useState(lottoNumbers);
const [winBalls, setWinBalls] = useState([]);
and setWinballs were used as follows.
for (let i = 0; i < winNumbers.length - 1; i++) {
timeouts.current[i] = setTimeout(() => {
setWinBalls((prevBalls) => [...prevBalls, winNumbers[i]]); <--------
}, (i + 1) * 1000);
What does 'setWinBalls((prevBalls) => [...prevBalls, winNumbers[i]])' mean here?
I didn't know that the 'set' function could have a function parameter.
The function setWinBalls() is using an arrow function which returns an object. Spread syntax has been used inside the arrow function which simply adds the current winNumber which is winNumbers[i] to the array and stores the updated array into another variable.
//example to understand what spread syntax does
var exampleArray = [1, 2, 3];
exampleArray = [...exampleArray, 4];
//exampleArray will be [1, 2, 3, 4]
Now let us try and understand what this arrow function is doing. The for loop can be written this way:
for (let i = 0; i < winNumbers.length - 1; i++) {
timeouts.current[i] = setTimeout(() => {
var updatedBalls = (prevBalls) => [...prevBalls, winNumbers[i]];
//winNumbers[i] will be added to the end to prevBalls array and updated array will be stored in updatedBalls
setWinBalls(updatedBalls);
}, (i + 1) * 1000);
Hope the code is clear to you now.

From a List representation of a Map, to a real Map in Scala

I want to transform a Seq of keys/values to a Map. The first element of the sequence is reserved, so the list of pairs starts in the position 1.
The question is: Is possible to implement this function using a more functional way?
def list2Map(plainMap:Seq[String]) = {
var map = Map[String, String]()
var idx = 1;
while(plainMap.size > idx) {
val key = plainMap(idx)
idx += 1
val value = plainMap(idx)
idx += 1
map = map + (key -> value)
}
map
}
assert( list2Map( Seq("reserved slot","key0","value0","key1","value1","key2","value2") ) == Map( ("key0"->"value0"),("key1"->"value1"),("key2"->"value2") ) )
I am new in Scala, and I know that there are a lot of different ways to iterate over a collection, but I don't found a forEach way to read two elements per iteration, starting in the element 1.
PS: Thanks folks. I am learning a lot with everyone response!!
list.drop(1).grouped(2).map { x => x.head -> x.last }.toMap
You mean something like this?:
val list = List("reserved slot", "key0", "value0", "key1", "value1", "key2", "value2")
val list4Map = list.tail.grouped(2).map { listBy2 => (listBy2(0), listBy2(1)) }.toList
val map = Map(list4Map: _*)
Maybe you would like some recursive one:
def seq2Map[T](seq: Seq[T]) = {
def rec(seq: Seq[T], map: Map[T,T] = Map.empty[T,T]): Map[T,T] = seq match {
case h :: t :: e => rec(e, map + (h -> t))
case _ => map
}
rec(seq.tail)
}
(for { Seq(k, v) <- list.tail.grouped(2) } yield k -> v).toMap
covers trailing key too

Order reversed in Aggregate LINQ query

I think the result should contain [1,1,2,2,3,3] but it contains [3,3,2,2,1,1]. Why is the list being reversed?
var sequence = new int[] { 1, 2, 3 };
var result = sequence.Aggregate(
Enumerable.Empty<int>(),
(acc, s) => Enumerable.Repeat(s, 2).Concat(acc));
Thanks
For every item in the sequence, you are concatenating the repetition to the beginning of the accumulated sequence. Swap the order so you are concatenating to the end.
(acc, s) => acc.Concat(Enumerable.Repeat(s, 2))
On a side note, it would be easier (and more efficient) to do this to get that sequence instead.
var result =
from s in sequence
from x in Enumerable.Repeat(s, 2)
select x;
Simpler way to achieve by using SelectMany:
var sequence = new int[] { 1, 2, 3 };
var result = sequence.SelectMany(i => new[] {i, i}).ToArray();

Linq - return index of collection using conditional logic

I have a collection
List<int> periods = new List<int>();
periods.Add(0);
periods.Add(30);
periods.Add(60);
periods.Add(90);
periods.Add(120);
periods.Add(180);
var overDueDays = 31;
I have a variable over due days. When the vale is between 0 to 29 then I want to return the index of 0. When between 30 - 59 I want to return index 1. The periods list is from db so its not hard coded and values can be different from what are here. What is the best way to to it using LINQ in one statement.
It's not really what Linq is designed for, but (assuming that the range is not fixed) you could do the following to get the index
List<int> periods = new List<int>();
periods.Add(0);
periods.Add(30);
periods.Add(60);
periods.Add(90);
periods.Add(120);
periods.Add(180);
var overDueDays = 31;
var result = periods.IndexOf(periods.First(n => overDueDays < n)) - 1;
You can use .TakeWhile():
int periodIndex = periods.TakeWhile(p => p <= overDueDays).Count() - 1;
how about this ?
var qPeriods = periods.Where(v => v <= overDueDays)
.Select((result, i) => new { index = i })
.Last();
Assuming that periods is sorted, you can use the following approach:
var result = periods.Skip(1)
.Select((o, i) => new { Index = i, Value = o })
.FirstOrDefault(o => overDueDays < o.Value);
if (result != null)
{
Console.WriteLine(result.Index);
}
else
{
Console.WriteLine("Matching range not found!");
}
The first value is skipped since we're interested in comparing with the upper value of the range. By skipping it, the indices fall into place without the need to subtract 1. FirstOrDefault is used in case overDueDays doesn't fall between any of the available ranges.

Linq OrderByDescending but keep zero value first

I have a collection of integers that I want to order by descending value, with the exception of keeping a 0 value as first in the list.
For example:
0,1,2,3,4,5,6,7,8
Should result in:
0,8,7,6,5,4,3,2,1
Thanks!
var input = new [] {0,1,2,3,4,5,6,7,8};
Two sortings which work with both negative and positive numbers:
var result = input.OrderBy(i => i == 0? 0 : 1).ThenByDescending(i => i);
or this if all your numbers are non-negative:
var result = input.OrderByDescending(i => i == 0? int.MaxValue : i);
or some really weird solution if you have both negative and positive numbers but you don't want to sort twice (as I'm doing in first solution):
var result = input
.GroupBy(i => i == 0 ? 0 : 1)
.OrderBy(g => g.Key)
.Select(g => g.Key == 0 ? g : g.OrderByDescending(i => i)
.SelectMany(g => g);

Resources