summing up values in an array - apache-flex

How do I sum up the values for my array? Here's the output if I trace my array (I couldn't find the actionscript equivalent of PHP's print_r function):
for(var k:int=0; k<tempAC.length; k++){
trace(tempAC[k].name);
trace(tempAC[k].value);
trace('-----------');
}
__OUTPUT__
Bob
3
-----------
Mary
5
-----------
Bob
12
-----------
Mary
1
How do I construct an array that would sum up Bob & Mary's respective values?
ie the Output would be:
Bob
15
------------
Mary
6
------------
I've got (where I try += to sum the values):
for(var k:int=0; k<tempAC.length; k++){
newAC['name']=tempAC[k].name;
newAC['value']+=tempAC[k].value;
}

var tempAC:Array = [
{name: "Bob", value: 3},
{name: "Mary", value: 5},
{name: "Bob", value: 12},
{name: "Mary", value: 1}
];
/**
* Combines values in objects that have identical names
* #param ar The array to assess
*/
function combine(ar:Array):Array
{
var hold:Array = [];
var back:Array = [];
var i:Object;
for each(i in ar)
{
if(!hold[i.name]) hold[i.name] = i.value;
else hold[i.name] += i.value;
}
var j:String;
for(j in hold)
{
back.push({name: j, value: hold[j]});
}
return back;
}
var list:Array = combine(tempAC);
var i:Object;
for each(i in list)
{
trace(i.name + ": " + i.value);
}
Output:
Bob: 15
Mary: 6

for(var k:int=0; k<tempAC.length; k++){
newAC[tempAC[k].name]+=tempAC[k].value;
}
That way you sum each name separately, regardless how many names u have there.
To see output:
(what ever is your print method, I'll call it echo)
echo newAC['THE NAME YOU WANT'];
b.t.w I have no idea about Flash, but the concept is good, and the syntax (except the echo) is also good.

Take a look at creating an Associative Array with a String Key. Read the article and it should get you started.

Related

How to properly use Partition and Sort Key

I know how to use the PK and SK but in my case it's a bit different.
I basically pass some distance and I want to retrieve the vehicles that can be used.
e.g:
HTTP Request passing the distance e.g. 50km so (bycicle, car and train need to be returned)
Basically I want to retrieve the vehicles that can be used
PK | distanceMin (SK) | distanceMax | vehicleName
distance | 0 | 10 | bycicle
distance | 10 | 500 | car // cannot have SK as 0
distance | 50 | 9999 | train // cannot have SK as 0
// This will have thousands of records
The problem is that I need to do scans for this and it's cost expensive and I also cannot use the same SK (0) for car and train because it would be a duplicate.
How can I pass a distance and make a query to get all the vehicles that are inside the range distanceMin and distanceMax?
My current code
searchByDistance: async function(distance) {
const search = parseInt(distance);
let params = {
TableName: this.myTable,
ScanIndexForward: true,
ConsistentRead: false,
KeyConditionExpression: 'PK=:pkKey AND distanceMin <= :search',
ProjectionExpression: 'vehicleName',
ExpressionAttributeValues: {
':pkKey': 'distance',
':search': search,
},
FilterExpression: 'distanceMax >= :search',
};
let scanResults = [];
let items;
try {
do {
items = await this.getDbClient().query(params).promise();
(items.Items || []).forEach((item) => scanResults.push(item));
params.ExclusiveStartKey = items.LastEvaluatedKey;
} while (typeof items.LastEvaluatedKey !== 'undefined');
} catch (err) {
console.log(err, err.stack);
}
return scanResults;
},

Karate; Counting # of K:V pairs within an object in a json array

For debugging purposes before writing out tests, I am looking to get the number of key:value pairs within the one object in the array.
Right now, I have this:
"items": [
{
"id": "6b0051ad-721d-blah-blah-4dab9cf39ff4",
"external_id": "blahvekmce",
"filename": "foo-text_field-XYGLVU",
"created_date": "2019-02-11T04:10:31Z",
"last_update_date": "2019-02-11T04:10:31Z",
"file_upload_date": "2019-02-11T04:10:31Z",
"deleted_date": null,
"released_and_not_expired": true,
"asset_properties": null,
"file_properties": null,
"thumbnails": null,
"embeds": null
}
]
When I write out:
* print response.items.length // returns 1
When I write out:
* print response.items[0].length it doesn't return anything
Any thoughts on how I can approach this?
There are multiple ways, but this should work, plus you see how to get the keys as well:
* def keys = []
* eval karate.forEach(response.items[0], function(x){ keys.add(x) })
* def count = keys.length
* match count == 12
Refer the docs: https://github.com/intuit/karate#json-transforms
Karate now provides karate.sizeOf() API to get count of an object.
* def object = { a: 1, b: 'hello' }
* def count = karate.sizeOf(object)
* match count == 2
Ref: https://github.com/karatelabs/karate#the-karate-object
count = 0
for (var v in response.items[0]) {
count = count + 1;
}
print(count)

Kotlin - group elements by a key under some conditions with new value type

I'm trying to find a way to use Kotlin collection operation to do some logic that I'm going to explain:
Let's say type Classroom contains a list of Student as a field in it, eg. classroom.getSudents() returns a list of certain studends.
Now I have a list of mixed Student that I need to group by one of its fields say major, and the value of the resultant map to be Classroom.
So I need to convert List<Student> to Map<Student.major, Classroom>
Also at some cases of major, for example for all major == chemistry, I'll need to group by another criteria, say firstname, so the keys of major chemistry would be major_firstname
Here's an example, I have a list of Student(major, firstname):
[
Student("chemistry", "rafael"),
Student("physics", "adam"),
Student("chemistry", "michael"),
Student("math", "jack"),
Student("chemistry", "rafael"),
Student("biology", "kevin")
]
I need the result to be:
{
"math" -> Classroom(Student("math", "jack")),
"physics" -> Classroom(Student("physics", "adam")),
"chemistry_michael" -> Classroom(Student("chemistry", "michael")),
"chemistry_rafael" -> Classroom(Student("chemistry", "rafael"), Student("chemistry", "rafael")),
"biology" -> Classroom(Student("biology", "kevin"))
}
I've tried groupBy, flatMapTo and associateBy but as far as I understand all of these doesn't group by a certain condition.
I will try to answer the 1st part as Roland posted an answer for the 2nd part (although I did not try it).
Assuming your classes are:
class Student(val major: String, val firstName: String)
class Classroom(val studentList: MutableList<Student>) {
fun getStudents(): MutableList<Student> {
return studentList
}
}
and with an initialization like:
val list = mutableListOf<Student>(
Student("chemistry", "rafael"),
Student("physics", "adam"),
Student("chemistry", "michael"),
Student("math", "jack"),
Student("chemistry", "rafael"),
Student("biology", "kevin"))
val classroom = Classroom(list)
val allStudents = classroom.getStudents()
you can have a result list:
val finalList: MutableList<Pair<String, Classroom>> = mutableListOf()
allStudents.map { it.major }.distinctBy { it }.forEach { major ->
finalList.add(major to Classroom(allStudents.filter { it.major == major }.toMutableList()))
}
so by the below code:
finalList.forEach {
println(it.first + "->")
it.second.getStudents().forEach { println(" " + it.major + ", " + it.firstName) }
}
this will be printed:
chemistry->
chemistry, rafael
chemistry, michael
chemistry, rafael
physics->
physics, adam
math->
math, jack
biology->
biology, kevin
It's actually the mixture of those methods which you require. There are also other ways to achieve it, but here is one possible example using groupBy and flatMap:
val result = students.groupBy { it.major }
.flatMap { (key, values) -> when (key) {
"chemistry" -> values.map { it.firstname }
.distinct()
.map { firstname -> "chemistry_$firstname" to ClassRoom(values.filter { it.firstname == firstname }) }
else -> listOf(key to ClassRoom(values))
}
}.toMap()
Assuming the following data classes:
data class Student(val major: String, val firstname: String)
data class ClassRoom(val students : List<Student>)
If you also want a map with all students grouped by major, the following suffices:
val studentsPerMajor = students.groupBy { it.major }
.map { (major, values) -> major to ClassRoom(values) }
If you then rather want to continue working with that map instead of recalculating everything from the source, it's also possible, e.g. the following will then return your desired map based on the studentsPerMajor:
val result = studentsPerMajor.flatMap { (key, classroom) -> when (key) {
"chemistry" -> classroom.students.map { it.firstname }
.distinct()
.map { firstname -> "chemistry_$firstname" to ClassRoom(classroom.students.filter { it.firstname == firstname }) }
else -> listOf(key to classroom)
}
}.toMap()

Is there a good way to use crossfilter to query multiple dimensions for unique values, not aggregates?

I've got a big set of data loaded into crossfilter for a dc.js project I'm working on. Of course a number of my columns have repeated values in them and I'd like to be able to find the unique list of values in one column that correspond to the repeated values in another. The sample data below probably illustrates the point more clearly.
var data = [
{ state: "WA", city: "Seattle", data: "a" },
{ state: "WA", city: "Seattle", data: "b" },
{ state: "WA", city: "Tacoma", data: "c" },
{ state: "OR", city: "Portland", data: "d" },
{ state: "OR", city: "Bend", data: "e" },
{ state: "OR", city: "Bend", data: "f" }
];
I'd like to be able to filter on a particular state and then find the unique list of cities for that state. So, if the input was "WA", I'd like get back a two element array containing "Seattle" and "Tacoma". The code below actually does exactly that (and also provides the counts, though I really don't care about those) but having to create a second crossfilter object feels very clumsy to me. I also don't know about the performance since I'll end up having to iterate through this several times, once for each state.
var Ndx = crossfilter(data);
var stateDim = Ndx.dimension(function (d) { return d.state; });
var cityDim = Ndx.dimension(function (d) { return d.city; });
var stateFilter = stateDim.filter("WA");
var stateRows = stateFilter.top(Infinity);
// It seems like there should be a better way than this.
var cityNdx = crossfilter(stateRows);
var cityDim2 = cityNdx.dimension(function (d) { return d.city; });
var cites = cityDim2.group().top(Infinity);
cites.forEach(function(d) {
console.log("City: " + d.key + ", Count: " + d.value);
});
/* --------------------------- *\
Log output:
City: Seattle, Count: 2
City: Tacoma, Count: 1
\* --------------------------- */
It seems like the should be a way to get to this kind of result with some filtering, grouping, or reducing strategy, but after spending way too much time trying, I haven't been able to come up with one. All the examples I've seen that use multiple dimensions produce aggregates, but that's not what I need. I need values. Is there a better way to go about this?
I'd use a custom reduce function to keep an array of all city values that have appeared for a given state. Something like the following (completely untested - sorry) should work:
var Ndx = crossfilter(data);
var stateDim = Ndx.dimension(function (d) { return d.state; });
var stateGroup = stateDim.group().reduce(
function(p, v) {
p.count++;
if(p.uniques.indexOf(v.city) === -1) p.uniques.push(v.city);
},
function(p, v) {
p.count--;
// Note: uniques are not filtered. You need to use a map and keep
// count of uniques to have uniques that match your current filter
},
function() {
return { count: 0, uniques: [] };
}
);
stateGroup.top(Infinity).forEach( function(g) {
console.log("State " + g.key + " has count " + g.value.count);
console.log("Unique cities in " + g.key + ":");
g.value.uniques.forEach(function (c) {
console.log(c);
});
});

how to add additional name-value pair in an existing flex object

folks,
I have a question regarding adding additional name-value pairs to my existing object in Flex;
I have an object1 of Object Type
and I declare a new object2 = object1 plus some extra name-value pairs,
is there a way to attach new name-value pairs to an existing object?
Many thanks,
If I understand your question correctly, object2 is a reference pointer to object1; therefore, changes to object2 affect object1:
package
{
import flash.display.Sprite;
public class X extends Sprite
{
public function X()
{
var object1:Object = {a: "1", b: "2"};
var object2:Object = object1;
object2.c = 3;
trace("Object 2:");
for (var name:String in object2)
{
trace("Name: " + name + " = " + object2[name]);
}
trace("Object 1:");
for (var name:String in object1)
{
trace("Name: " + name + " = " + object1[name]);
}
}
}
}
...which outputs:
Object 2:
Name: a = 1
Name: c = 3
Name: b = 2
Object 1:
Name: a = 1
Name: c = 3
Name: b = 2
If you are asking whether an object or dynamic class may be cloned, you could use a function like this:
public function cloneObject(object:Object):Object
{
var newObject:Object = {};
for (var name:String in object)
{
newObject[name] = object[name];
}
return newObject;
}

Resources