Continuously add data to Map - dictionary

I need to add data to a Map or HashMap before a for...loop, add data to the Map during the for...loop and then create the document with all of the data after the loop.
In Java for Android I used:
Map<String, Object> createDoc = new HashMap<>();
createDoc.put("type", type);
createDoc.put("title", title);
for (int x = 0; x < sArray.size(); x++) {
createDoc.put("data " + x,sArray.get(x));
}
firebaseFirestoreDb.collection("WPS").add(createDoc);
My question is, how would I create the document and immediately get the ID of it to then update/merge it with the rest of the data? Or is there a way to add data to a Map in Dart?
The only thing I've found in Dart is:
Map<String, Object> stuff = {'title': title, 'type': type};
and in the for...loop:
stuff = {'docRef $x': docId};
and after the for...loop:
Firestore.instance.collection('workouts').add(stuff);
which creates a document with only the last entry from the for...loop.
I also imported dart:collection to use HashMap, but it won't let me use
Map<String, Object> newMap = new HashMap<>();
I get the error: "A value of type 'HashMap' can't be assigned to a variable of type 'Map<String, Object>'"
Thank you in advance!

An equivalent block of code to what you wrote in Java, for Dart, is:
Map<String, Object> createDoc = new HashMap();
createDoc['type'] = type;
createDoc['title'] = title;
for (int x = 0; x < sArray.length; x++) {
createDoc['data' + x] = sArray[x];
}
Of course, Dart has type inference and collection literals, so we can use a more short-hand syntax for both. Let's write the exact same thing from above, but with some more Dart (2) idioms:
var createDoc = <String, Object>{};
createDoc['type'] = type;
createDoc['title'] = title;
for (var x = 0; x < sArray.length; x++) {
createDoc['data' + x] = sArray[x];
}
OK, that's better, but still is not using everything Dart provides. We can use the map literal instead of writing two more lines of code, and we can even use string interpolation:
var createDoc = {
'type': type,
'title': title,
};
for (var x = 0; x < sArray.length; x++) {
createDoc['data$x'] = sArray[x];
}
I also imported dart:collection to use HashMap, but it won't let me
use
Map<String, Object> newMap = new HashMap<>(); I get the error: `"A value of type 'HashMap' can't be assigned to a variable of type
'Map'`"
There is no such syntax new HashMap<> in Dart. Type inference works without it, so you could just write Map<String, Object> map = new HashMap(), or like my above example, var map = <String, Object> {}, or even better, var map = { 'type': type }, which will type the map for you based on the key and value.
I hope that helps!

Related

Java8 Create Map grouping by key contained in values

I have the following two lists of String:
{APPLE, ORANGE, BANANA} //call it keyList
{APPLE123, ORANGEXXX, 1APPLE, APPLEEEE} //call it valueList
Desired output is an HashMap<String, List<String>> like this:
<APPLE, {APPLE123, 1APPLE, APPLEEEE}>
<ORANGE, {ORANGEXXX}>
<BANANA, {}> //also <key, null> is accepted
I have implemented this solution(it works)
HashMap<String, List<String>> myMap = new HashMap<>();
keyList.forEach(key -> {
List<String> values = valueList.stream()
.filter(value -> value.contains(key))
.collect(Collectors.toList());
myMap.put(key, values);
});
Given the assumption that a value is related to only one key (it's a constraint of my domain), is this the best solution in java8 , in terms of performance and/or code cleaning ?
Can it be tuned in some way?
If you can safely assume that each value is associated with a key, and only one key, you can go into the following direction:
Pattern p = Pattern.compile(String.join("|", keyList));
Map<String, List<String>> map = valueList.stream()
.collect(Collectors.groupingBy(s -> {
Matcher m = p.matcher(s);
if(!m.find()) throw new AssertionError();
return m.group();
}));
map.forEach((k,v) -> System.out.println(k+": "+v));
If the keys may contain special characters which could get misinterpreted as regex constructs, you can change the preparation code to
Pattern p = Pattern.compile(
keyList.stream().map(Pattern::quote).collect(Collectors.joining("|")));
The collect operation does only create the groups for existing values. If you really need all keys to be present, you can use
Map<String, List<String>> map = valueList.stream()
.collect(Collectors.groupingBy(s -> {
Matcher m = p.matcher(s);
if(!m.find()) throw new AssertionError();
return m.group();
},
HashMap::new, // ensure mutable map
Collectors.toList()
));
keyList.forEach(key -> map.putIfAbsent(key, Collections.emptyList()));
or
Pattern p = Pattern.compile(
keyList.stream().map(Pattern::quote)
.collect(Collectors.joining("|", ".*(", ").*")));
Map<String, List<String>> map = valueList.stream()
.map(p::matcher)
.filter(Matcher::matches)
.collect(Collectors.groupingBy(m -> m.group(1),
HashMap::new, // ensure mutable map
Collectors.mapping(Matcher::group, Collectors.toList())
));
keyList.forEach(key -> map.putIfAbsent(key, Collections.emptyList()));

DeExpress MVC 17.1 How populate TokenBox from a database

I want populate a TokenBox from a database using the property tokenBoxSettings.Properties.DataSource
TokenBoxView.cshtml
groupSettings.Items.Add(
formLayoutSettings.Items.Add(i =>
{
i.FieldName = "email";
i.Caption = "Email";
i.NestedExtensionType = FormLayoutNestedExtensionItemType.TokenBox;
TokenBoxSettings tokenBoxSettings = (TokenBoxSettings) i.NestedExtensionSettings;
tokenBoxSettings.Width = 350;
//data binding
tokenBoxSettings.Properties.DataSource = mainController.GetMails();
tokenBoxSettings.Properties.TextField = "email_empresarial";
tokenBoxSettings.Properties.ValueField = "email_empresarial";
tokenBoxSettings.Properties.IncrementalFilteringMode = IncrementalFilteringMode.Contains;
tokenBoxSettings.Properties.ValueSeparator = ';';
})
);
TokenBoxController.cs
//mainController
//I created a dictionary based on the result of select
public Dictionary<string, string> GetMails()
{
var email = db.usuario.ToList().Select(e => new { e.email_empresarial });
var emails = new Dictionary<string, string>();
foreach (var mail in email)
{
correos.Add(mail.ToString(), mail.ToString());
}
return emails;
}
But it shows me the "object explicitly", I only need the value, for example kenneth or manuel
tokenBox list
What am I doing wrong? or with what other approach I can do?
You are specifying same email_empresarial field name for both tokenBoxSettings.Properties.TextField and tokenBoxSettings.Properties.ValueField.
Since you are binding your TokenBox to Dictionary, try changing settings for TextField and ValueField to reference Dictionary Key and Value, like this:
tokenBoxSettings.Properties.TextField = "Value";
tokenBoxSettings.Properties.ValueField = "Key";
Also, in your GetMail() method you have declared the var emails but in the loop you are adding items to the undeclared correos variable. Are you sure you don't have a bug here?
Another note, in the Dictionary returned by GetMails() you populate both dictionary keys and values with the same value of mail.ToString(). Are you sure you really need to use Dictionary to bind your TokenBox? If keys and values are equal you may try going with plain List<string>.

Create list of map using streams and lambda expressions

for (String varValue : arrayList1) {
Map<String, String> mapInstance = new HashMap<>();
val.put(KEY, VALUE);
val.put(VAR_KEY, varValue);
arrayList2.add(mapInstance);
}
Basically, I want to create a map with two entries and then add each of these maps to a list.
Final list:
{KEY,VALUE} {VAR_KEY,arrayList1.get(0)}
{KEY,VALUE} {VAR_KEY,arrayList1.get(1)}
{KEY,VALUE} {VAR_KEY,arrayList1.get(2)}
...
and so on
It seems you only need a simple map stage.
List<Map<String, String>> list = arrayList1.stream().map(t -> {
Map<String, String> map = new HashMap<>();
map.put("KEY", "VALUE");
map.put("VAR_KEY", t);
return map;
}).collect(Collectors.toList());
What is KEY and VAR_KEY? are they instance variable of some object which you are trying to put in Map from the incoming object.
However, you can try something like this :
Map result =
arrayList1.stream().collect(Collectors.toMap(Class::getKey, c -> c));

google places api many filters by type Ex.: restaurant,cafe

I'm trying to change the radius category/type filter for a checkbox, so I changed the var type to an array.
ORIGINAL WORKING:
var type;
for (var i = 0; i < document.controls.type.length; i++){
if (document.controls.type[i].checked){
type = document.controls.type[i].value;
}
}
startBox.setBounds(map.getBounds());
var search = {
// keyword: 'comocomo', // not needed with the autocomplete / startBox
bounds: map.getBounds()
};
if (type != 'establishment'){
search.types = [ type ];
}
places.search(search, function(placesArr, status){
THE ONE WITH THE ARRAY NOT WORKING: edited:
var type=[];
for (var i = 0; i < document.controls.type.length; i++){
if (document.controls.type[i].checked){
type.push(document.controls.type[i].value)
}
}
startBox.setBounds(map.getBounds());
var search = {
bounds: map.getBounds()
};
var quotedAndCommaSeparated = "'" + type.join("','") + "'";
alert(quotedAndCommaSeparated); // 'establishment','restaurant','lodging'
search.types = [ quotedAndCommaSeparated ];
I made many tests, and I don't see what I'm doing wrong. the map doesn't even show.
What's this meant to be, doesn't look like valid Javascript to me:
var type[];
Should be
var type = [];
Fix the javascript errors in your code otherwise the map won't show up.
Update:
What you have in quotedAndCommaSeparated is a string like "'a','b','c'" that looks a bit like the contents of an array: ['a','b','c']. But it's not an array, it's just a single string. If you check the length of your search.type array, I'm guessing it equals 1.
What you can do is split your string on the comma to turn it into an array:
search.types = quotedAndCommaSeparated.split(",");

Flash/Flex: Is it possible to encode Dictionary using AMF?

As the title suggests, is it possible to use AMF to encode/decode Dictionaries (without subclassing, that is)?
For example, here's a test case:
function serializeAndReload(obj:*):* {
var serialized:ByteArray = new ByteArray();
serialized.writeObject(obj);
serialized.position = 0;
return serialized.readObject();
}
function test():void {
var d:Dictionary = new Dictionary();
d[{}] = 42;
d[d] = true;
var x:* = serializeAndReload(d); // <<< x is an instance of Object
trace(x['[object Object]']); // <<< traces '42'
}
You may be over-thinking. I use Object instead of Dictionary and it is automatically encoded using AMF. I use pyamf all the time to pass Objects/dicts around and its always worked without any mental effort on my part. Never have I needed to manually serialize/deserialize anything
The keys in the Dictionary need to be serializable, too.
[RemoteClass(alias="Foo")]
public class Foo
{
}
Test:
var d:Dictionary = new Dictionary();
var f:Foo = new Foo();
d[f] = "Hello";
var ba:ByteArray = new ByteArray();
ba.writeObject(d);
ba.position = 0;
var d2:Dictionary = Dictionary(ba.readObject());
for (var key:* in d2)
{
trace(getQualifiedClassName(key));
trace(d2[key]);
}
Output:
Foo
Hello

Resources