Flutter Dart Map update multiple Values for one Key - list

How to update multiple value in one key?
Map<DateTime, List> _event;
_event.update(day, (contents) => contents..add(listNum),
ifAbsent: () => [listNum]); //type Int
_event.update(day, (contents) => contents..add(title),
ifAbsent: () => [title]); //type String
_event.update(day, (contents) => contents..add(details),
ifAbsent: () => [details]); //type String
I tried it by upper code, but it generate only 3 multiple maps, not value(elements in List)
is there any way to updates multiple Value by simple way?
thanks.

Related

How to remove double quotes from keys in RDD and split JSON into two lines?

I need to modify the data to give input to CEP system, my current data looks like below
val rdd = {"var":"system-ready","value":0.0,"objectID":"2018","partnumber":2,"t":"2017-08-25 11:27:39.000"}
I need output like
t = "2017-08-25 11:27:39.000
Check = { var = "system-ready",value = 0.0, objectID = "2018", partnumber = 2 }
I have to write RDD map operations to achieve this if anybody suggests better option welcome. colcount is the number of columns.
rdd.map(x => x.split("\":").mkString("\" ="))
.map((f => (f.dropRight(1).split(",").last.toString, f.drop(1).split(",").toSeq.take(colCount-1).toString)))
.map(f => (f._1, f._2.replace("WrappedArray(", "Check = {")))
.map(f => (f._1.drop(0).replace("\"t\"", "t"), f._2.dropRight(1).replace("(", "{"))) /
.map(f => f.toString().split(",C").mkString("\nC").replace(")", "}").drop(0).replace("(", "")) // replacing , with \n, droping (
.map(f => f.replace("\" =\"", "=\"").replace("\", \"", "\",").replace("\" =", "=").replace(", \"", ",").replace("{\"", "{"))
Scala's JSON parser seems to be a good choice for this problem:
import scala.util.parsing.json
rdd.map( x => {
JSON.parseFull(x).get.asInstanceOf[Map[String,String]]
})
This will result in an RDD[Map[String, String]]. You can then access the t field from the JSON, for example, using:
.map(dict => "t = "+dict("t"))

slick 3 two leftJoin query result to classes mapping

Current question is relative with next one, but now I need to read the data from database instead of insert.
I have next three case classes:
case class A (id: Long, bList: List[B])
case class B (id: Long, aId: cList: List[C])
case class C (id: Long, bId: Long)
And query with two leftJoin functions and incomingAId for filtering aTable results:
val query = (for {
((aResult,bResult),cResult) <- aTable.filter(_.id === incomigAId)
.joinLeft(bTable).on(_.id === _.aId)
.joinLeft(cTable).on(_._2.map(_.id) === _.bId)
} yield ((aResult,bResult),cResult)).result.transactionally
Next query works and the result looks valid, but isn't easy to handle it to the case classes. Also, executionResult has Seq[Nothing] type and process of mapping requires something like that:
database.run(query).map{ executionResult =>
executionResult.map { vectorElement: [Tuple2[Tuple2[A, Option[B]], Option[C]]]
...
}
}
Is there any proper way to prevent Seq[Nothing] (changes in query)?
Or if the query result type is fine, could you please share solution how to map it to the case classes above?
Right now I'm using next solution, but I suppose that some part of code can be optimized (e.g. groupBy replacing with something else).
execute(query).mapTo[Vector[((A, Option[B]), Option[C])]]
.flatMap { insideFuture =>
insideFuture.groupBy(_._1._1).mapValues { values =>
//scala groupBy losts ordering
val orderedB = values.groupBy(_._1._2).toSeq.sortBy(_._1.map(_.id)).toMap
orderedB.mapValues(_.map(_._2))
}.headOption match {
case Some(data) => Future.successful {
data._1.copy(bList = data._2.map {
case (Some(bElement), optionCElements) =>
bElement.copy(cList = optionCElements.toList.flatten)
case _ =>
throw new Exception("Invalid query result. Unable to find B elements")
}.toList)
}
case None => Future.failed(new Exception("Unable to find A with next id " + incomigAId))
}
}
}

Regex Using dynamic named subpattern?

I am doing something like this to prepare a dynamic regex.
$mapping = "asa/user/{u}/d/{d}/{f}"; //line 1
$mapper = preg_replace('/\{.*?\}/m','(\w+)',str_replace('/','#',$mapping)); //line 2
preg_match("/".$mapper."/",str_replace('/','#',$input),$arr);
print_r($arr);
which give output like this for $input = /asa/user/ZZA/d/asasa/gh
Array ( [0] => asa#user#ZZA#d#asasa#gh [1] => ZZA [2] => asasa [3] => gh )
What I want is to get something like this.
Array ( [u] => ZZA [d] => asasa [f] => gh )
I know I can do this with using ?P, so trying this
$mapper = preg_replace('/\{.*?\}/m','(?P<name>\w+)',str_replace('/','#',$mapping));
Which obviously would not work as it will use same index name for all params,what i need to do is replace name with u,d,f dynamically.
i can do this with explode i believe, then traversing the array and replace one by one. But is there any better solution to do this type of operation?
At line 2 can read value between braces and then use it as index to replace with?
At line 2 can read value between braces and then use it as index to
replace with?
Yes, by capturing groups () and backrefrences $n.
You should change the second line to:
$mapper = preg_replace('/\{(.*?)\}/m','(?P<$1>\w+)', str_replace('/','#',$mapping));
Which results in:
Array
(
[0] => asa#user#ZZA#d#asasa#gh
[u] => ZZA
[1] => ZZA
[d] => asasa
[2] => asasa
[f] => gh
[3] => gh
)

QueryBuilder alias for expr() in select() method

is there any option to set alias for $qb->expr()->avg('e.value') in select() method of Doctrine2 query builder?
I have e.g. this query:
$qb->select($qb->expr()->avg('e.value'), 'e someAlias')->from('Entity', 'e');
But the average value is indexed by integer in the result, like this:
array(
0 => array(
'someAlias' => Entity {},
1 => 2.5255,
),
);
Is it possible to change key of the average value to the defined string value?
Try the following to set the alias:
$qb->select(array(
$qb->expr()->select()->avg('e.value').' AS aveAlias')
,'e someAlias')
)->from('Entity', 'e');

Faking an enumerator in FakeItEasy

How can I create a fake with FakeItEasy that allows different return values on successive calls. This is one example of what I would like to be able to do:
var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(true); //Expected value for first call
A.CallTo(() => enumerator.Key).Returns("key1");
A.CallTo(() => enumerator.Value).Returns("value1");
A.CallTo(() => enumerator.MoveNext()).Returns(false); //Expected value for second call
Assert.IsTrue(enumerator.MoveNext()); //Fails
Assert.IsFalse(enumerator.MoveNext());
The assertion will fail since it the last set up of MoveNext will overwrite the first one.
Is it possible to do what I want in FakeItEasy?
.
[Edit]
Clarified the original question's example and provided a working example below.
Based on Patrik's answer this code shows how you can set up the fake. The trick is to reverse all setups and use Once().
var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
A.CallTo(() => enumerator.MoveNext()).Returns(true).NumberOfTimes(2);
A.CallTo(() => enumerator.Key).Returns("key2").Once();
A.CallTo(() => enumerator.Value).Returns("value2").Once();
A.CallTo(() => enumerator.Key).Returns("key1").Once();
A.CallTo(() => enumerator.Value).Returns("value1").Once();
while(enumerator.MoveNext())
{
Debug.WriteLine(enumerator.Key + ": "+ enumerator.Value);
}
This will print:
key1: value1
key2: value2
I'm not entirely sure that I understand what you mean, the code you supplied will always fail. However if you mean that you want it to return true the second time it's called it can be done. There are a couple of different ways that I can think of, two of them are:
A.CallTo(() => enumerator.MoveNext()).ReturnsNextFromSequence(false, true);
The other way is:
A.CallTo(() => enumerator.MoveNext()).Returns(true);
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
Edit:
On second though I guess I understand your question better, what you want to happen is that MoveNext should return true the first time and false the second time? If that's the case just change the orders of the values in the examples above.
FakeItEasy does not use a record/replay model and you are correct in that the latest configured rule has precedence over any earlier specified rules. That's why you have to specify repeat - ".Once()" - on the latest configuration for it only to be valid once.
There are many reasons why the latest has precedence, one of the most important ones is that it lets you set up a default return value in the setup of your fixture and override it to return specific values in some of your tests, this is impossible when using a record/replay model.
The OP's example based on Patrik's answer is fine ... but tedious if the sequence grows large. To supplement that answer consider that even though fake/mock examples most often show a bunch of straight line code to Arrange themselves you actually have the full power of a programming language at your command. Conditionals, loops, and even procedures.
So consider the following:
public static void AFakeDictionaryEnumeratorReturns(
IDictionaryEnumerator enumerator, params object[] pairs)
{
if (0 != pairs.Length % 2)
throw new ArgumentException("pairs must have even number of elements", "pairs");
int n = pairs.Length / 2;
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
A.CallTo(() => enumerator.MoveNext()).Returns(true).NumberOfTimes(n);
for (int i = pairs.Length; i > 0; i -= 2)
{
A.CallTo(() => enumerator.Key).Returns(pairs[i - 2]).Once();
A.CallTo(() => enumerator.Value).Returns(pairs[i - 1]).Once();
}
}
and now the test becomes:
var enumerator = A.Fake<IDictionaryEnumerator>();
AFakeDictionaryEnumeratorReturns(enumerator,
"key1", "value1", "key2", "value2", "key3", "value3");
var keys = new List<object>();
var values = new List<object>();
while (enumerator.MoveNext())
{
keys.Add(enumerator.Key);
values.Add(enumerator.Value);
}
Assert.Equal(new List<object> { "key1", "key2", "key3" }, keys);
Assert.Equal(new List<object> { "value1", "value2", "value3" }, values);
(An IDictionaryEnumerator deals in pairs, so this example isn't as clearly beneficial as it could be. For a standard IEnumerator<T> a single static generic method would serve for a whole bunch of different enumerators.)