How to increment a value in a map with Apex? - dictionary

Is there a way to increment a value in a map without needing a second variable?
for example, this doesn't work:
counts = new Map<string,integer>();
counts.put('month_total',0);
counts.put('month_total',counts.get['month_total']++);
it returns "Initial term of field expression must be a concrete SObject: MAP"
instead I needed to do:
counts = new Map<string,integer>();
counts.put('month_total',0);
integer temp = 0;
temp++;
counts.put('month_total',temp);
is there any way to increment without needing an extra variable?

Replace
counts.put('month_total',counts.get['month_total']++);
with
counts.put('month_total',counts.get('month_total')++);

List<String> lststrings = new List<String>{'key','wewe','sdsd','key','dfdfd','wewe'};
Map<String,Integer> mapval = new Map<String,Integer>();
Integer count = 1;
for(string str : lststrings){
IF(mapval.containsKey(str)){
mapval.put(str,mapval.get(str)+1);
}
else{
mapval.put(str,count);
}
}
system.debug('value of mapval'+mapval);

Related

How to group all duplicate object to one list and all unique object to another list from a original list in C#?

I have a text file and to read from and convert each line to and object with Id and someText. I would like to group them so that I have two lists: unique list and duplicate list. the data is very big up to hundred of thousand of lines. Which is the best data structure to use? Please provide some sample code in C#. Thanks a lot!
for example:
original list read from text file:
{(1, someText),(2, someText),(3, someText),(3, someText1),(4, someText)}
unique list:
{(1, someText),(2, someText),(4, someText)}
duplicate list:
{(3, someText),(3, someText1)}
Here's an example with LinQ
Random rnd = new Random();
StreamReader sr = new StreamReader("enterYourPathHere");
string line = "";
int cnt = 0; //This will "generate our ids".
List<KeyValuePair<int,string>> values = new List<KeyValuePair<int, string>>();
while ((line = sr.ReadLine()) != null)
{
//You convert the line to your object (using keyvaluepair for testing)
var obj = new KeyValuePair<int, string>(cnt, line);
values.Add(obj);
//Increment the id on with 50% chances
if (rnd.Next(0,1) >0.5) cnt++;
}
var unique = values.GroupBy(x=>x.Key).Distinct().Select(x=>x).ToList();
var duplicates = values.GroupBy(x => x.Key).Where(x => x.Count() > 1).Select(x => x).ToList();

Specific row withing a DataTable

I have a data table which has a "Total" column. I want to be able to get a specific rows "Total" not all rows.
public void maxValue()
{
string pass = (String)Session["name"];
DataTable table = (DataTable)Session["CocaCola"];
int total = table.AsEnumerable().Sum(r => r.Field<int>("Total"));
int totalAllowed = table.AsEnumerable().Sum(r => r.Field<Int32>("Total Allowed"));
if (total >= totalAllowed)
{
Label1.Text = "Total value exceeded the maximum of " + totalAllowed;
}
else if (total < totalAllowed)
{
Label1.Text = "Total value which is allowed :" + totalAllowed;
}
if (pass.Equals("Low"))
{
Label1.Text = "You are not allowed any assets at this Stage";
//SNS.Checked = false;
//TT.Checked = false;
//Music.Checked = false;
//SNS.Enabled = false;
//TT.Enabled = false;
//Music.Enabled = false;
}
}
As you can see my method works but add the column up which i dont want to do. How would i go about changing it?
You can do it this way
int yourTargetindex = 0; //Change this to get the value of your target element
int total =(from row in table.AsEnumerable()
select row.Field<int>("Total")).ElementAt(yourTargetindex);
//This will return the first value of "total" in the DataTable
You don't have to use linq. DataTable has built-in methods for this kind of operations:
var selectedTotal = table.Compute("sum(Total)", "columnX == 'x'");
This tell the table to calculate the sum of all Total cells in rows where columnX has the specified value.
Of course you can use linq. You would need to add a Where() before you calculate the sum.

Field type returning numbers [Axapta]

I want to get the field types. My code is as follows:
tID = dict.tableName2Id(tableName);
counter = 0;
dt = new DictTable(tID);
if (dt)
{
counter = dt.fieldNext(counter);
while (counter)
{
df = dt.fieldObject(counter);
if (df)
{
fields = conIns(fields,1,df.baseType());
}
counter = dt.fieldNext(counter);
}
}
On return to .NET Business connector, the types are shown as numbers instead of strings.
Kindly help.
EDIT : DataField.baseType() returns "Types" can this be converted to string and then added to the container?
EDIT 2: Ok now, im getting a Types Enumeration. Is there any way to map this enumeration in AX and add to container as string?
Got it!! Here's the code :
tID = dict.tableName2Id(tableName);
counter = 0;
dt = new DictTable(tID);
if (dt)
{
counter = dt.fieldNext(counter);
while (counter)
{
df = dt.fieldObject(counter);
if (df)
{
t = df.baseType();
fields = conIns(fields,1,enum2str(t));
}
counter = dt.fieldNext(counter);
}
}

Flex AS3 Arraycollection sorting based on Array of values

I have been working on sorting Arraycollection like ascending , descending the numeric list. Total length of my collection will go up to 100. Now I want to preform sort to nested data like this
Data Structure
Name : String
Categories : Array ["A","x or y or z","C"]
Categories array will have maximum 3 items , out of that three items the second item can have 3 different values either X or Y or Z. My result data looks like here
{"Mike" , ["A","x","C"]}
{"Tim" , ["A","y","C"]}
{"Bob" , ["A","x","C"]}
{"Mark" , ["A","z","C"]}
{"Peter" , ["A","z","C"]}
{"Sam" , ["A","y","C"]}
anyone please explain how to sort this type of data in a way showing all "x" first , "y" next and "z" at the last and vice a versa. Any help is really appreciated. Thanks Anandh. .
You can specify a compare function in your SortField like this:
var sortfield:SortField = new SortField("Categories");
sortfield.compareFunction = myCompare;
var sort:Sort = new Sort();
sort.fields = [sortfield];
yourCollection.sort = sort;
and your compare function:
function myCompare(a:Object, b:Object):int {
/*
return -1, if a before b
return 1, if b before a
return 0, otherwise
*/
}
or something like that.. and it's untested code :)
I have created a new property to the data structure called categoryOrder In the setter I did the following and Am using the categoryOrder for sorting - sortBy = categoryOrder;. I understand little hard coding is needed but still I believe this will reduce the number of comparisons when I use compareFunction. Anyone please valid this idea. Thanks!
public function set categories(data:ArrayCollection) :void
{
if(data != null)
{
_categories = data;
for each(var categorie:Object in data)
{
switch(categorie.categoryName)
{
case "x":{categoryOrder = 1;break;}
case "y":{categoryOrder = 2;break;}
case "z":{categoryOrder = 3;break;}
}
}
}
}
Data Structure
Name : String
Categories : Array ["A","x or y or z","C"]
categoryOrder : Number

How to do Previous and Next item on a List<G>

I have a class called Person, which contains various properties such as first name, last name, etc.
I have a List that contains n instances of Person.
List<Person> lstPerson = new List<Person>();
What I need to be able to do is search lstPerson for a given person, and having found that person then obtain the previous and next person relative to the person's item position in lstPerson.
Person p = lstPerson.Find(delegate(Person o) { return o.FirstName == "Joe"; });
// Then use an accessor to get the previous and next persons
Person prevPerson = p.Previous();
Person nextPerson = p.Next();
Is there a better way to do this then the one that I stated above? What I don't like about the above solution is that I have to construct the previous and next pointers at the time that I build the Person List.
You could do something like the following:
int personIndex = lstPerson.FindIndex(delegate(Person o) { return o.FirstName == "Joe" });
Person p = lstPerson[personIndex];
// verify that personIndex+1 and personIndex-1 still fall within the list
Person prevPerson = lstPerson[personIndex-1];
Person nextPerson = lstPerson[personIndex+1];
Hmm.. why not simply using the LinkedList class?
It comes with Next and Previous built in.
You could do this, which skips elements until the next element matches or it has gone through the entire list:
var list = (new List<Person>() { null }).Concat(lstPerson);
var p = list.SkipWhile((x, index) => { var n = list.ElementAtOrDefault(index + 1); return n == null || n.FirstName != name; }).Take(3);
Person previous = p.FirstOrDefault();
Person person = p.ElementAtOrDefault(1);
Person next = p.ElementAtOrDefault(2);
Although this (similar to #marcind's answer) might be clearer:
Person person = lstPerson.Find(p => p.FirstName == name);
Person previous = null;
Person next = null;
if (person != null)
{
int index = lstPerson.IndexOf(person);
previous = lstPerson.ElementAtOrDefault(index - 1);
next = lstPerson.ElementAtOrDefault(index + 1);
}

Resources