How to build params based on the length of the array? - asp.net-mvc

function BuildParams(arr)
{
// arr is an Array
// how to build params based on the length of the array?
// for example when arr.Length is 3 then it should build the below:
var params = {
'items[0]' : arr[0],
'items[1]' : arr[1],
'items[2]' : arr[2]
},
return params;
}
Then I'd like to be able to send it to my ajax get:
var arr = ['Life', 'is', 'great'];
$.get('/ControllerName/ActionName', BuildParams(arr))
.done(function(data, status) {
alert("Data: " + data + "\nStatus: " + status);
})
.fail(function(data) {
alert(data.responseText);
});

var result = {}
jQuery.each(['Life', 'is', 'great'], function(index, value){
result['items[' + index + ']'] = value;
});
jQuery.each:
A generic iterator function, which can be used to seamlessly iterate
over both objects and arrays. Arrays and array-like objects with a
length property (such as a function's arguments object) are iterated
by numeric index, from 0 to length-1. Other objects are iterated via
their named properties.

Just iterate over the array, adding each element in the array as a new property of a params object:
var params = {}; // start with an empty object
for(var i = 0; i < arr.length; i++) {
params["items[" + i + "]"] = arr[i];
}
return params; // return the populated params object

Change BuildParams(arr) to:
{items: arr}
jQuery will correctly serialize objects into query-strings, including objects with items that are arrays.

Related

Dart converting String to Array then compare two array

I'm trying to convert strings to arrays then compare two arrays. If the same value needs to remove from both array. Then finally merge two arrays and find array length. Below is my code
String first_name = "siva";
String second_name = "lovee";
List<String> firstnameArray=new List();
List<String> secondnameArray=new List();
firstnameArray = first_name.split('');
secondnameArray = second_name.split('');
var totalcount=0;
for (int i = 0; i < first_name.length; i++) {
for (int j = 0; j < second_name.length; j++) {
if (firstnameArray[i] == secondnameArray[j]) {
print(firstnameArray[i] + "" + " == " + secondnameArray[j]);
firstnameArray.removeAt(i);
secondnameArray.removeAt(i);
break;
}
}
}
var finalList = new List.from(firstnameArray)..addAll(secondnameArray);
print(finalList);
print(finalList.length);
But always getting this error Unsupported operation: Cannot remove from a fixed-length list can you help me how to fix this issue. Thanks.
Seems like what you are trying to do is to find the length of unique characters in given two strings. Well, the Set type is perfect for this use-case. Here's an example of what you can do:
void main() {
String first = 'abigail';
String second = 'allie';
var unique = '$first$second'.split('').toSet();
print(unique);
}
This would give you an output of:
{a, b, i, g, l, e}
On which you may perform functions like .toList(), or .where() or .length.
You can ensure that firstnameArray, secondnameArray is not a fixed-length list by initializing it as below:
var firstnameArray = new List<String>.from(first_name.split(''));
var secondnameArray= new List<String>.from(second_name.split(''));
Thereby declaring firstnameArray, secondnameArray to be a mutable copy of input.

Accessing jsonpath elements with nested objects

I am looking to extract certain values from a JSON path of arrays and objects and use these values for further processing and am struggling with accessing those elements. Here is the JSON response:
[
{
"od_pair":"7015400:8727100",
"buckets":[
{
"bucket":"C00",
"original":2,
"available":2
},
{
"bucket":"A01",
"original":76,
"available":0
},
{
"bucket":"B01",
"original":672,
"available":480
}
]
},
{
"od_pair":"7015400:8814001",
"buckets":[
{
"bucket":"C00",
"original":2,
"available":2
},
{
"bucket":"A01",
"original":40,
"available":40
},
{
"bucket":"B01",
"original":672,
"available":672
},
{
"bucket":"B03",
"original":632,
"available":632
},
{
"bucket":"B05",
"original":558,
"available":558
}
]
}
]
I tried accessing the root elements with $ but I could not get further with it.
Here is the test method that I have written. I want to extract the value for od_pair and within each od_pair, I need to be able to retrieve the bucket codes and their available numbers.
public static void updateBuckets(String ServiceName, String DateOfJourney) throws Exception {
File jsonExample = new File(System.getProperty("user.dir"), "\\LogAvResponse\\LogAvResponse.json");
JsonPath jsonPath = new JsonPath(jsonExample);
List<Object> LegList = jsonPath.getList("$");
// List<HashMap<String, String>> jsonObjectsInArray = jsonPath.getList("$");
int NoofLegs = LegList.size();
System.out.println("No of legs :" + NoofLegs);
for (int j = 0; j <= NoofLegs; j++)
// for (HashMap<String, String> jsonObject : jsonObjectsInArray) {
{
String OD_Pair = jsonPath.param("j", j).getString("[j].od_pair");
// String OD_Pair = jsonObject.get("od_pair");
System.out.println("OD Pair: " + OD_Pair);
List<Object> BucketsList = jsonPath.param("j", j).getList("[j].buckets");
int NoOfBuckets = BucketsList.size();
// System.out.println("OD Pair: " + OD_Pair);
System.out.println("no of Buckets: " + NoOfBuckets);
for (int i = 0; i < NoOfBuckets; i++) {
String BucketCode = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].bucket");
String Available = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].available");
int BucketCodeColumn = XLUtils.getBucketCodeColumn(BucketCode);
int ServiceRow = XLUtils.getServiceRow(ServiceName, DateOfJourney, OD_Pair);
System.out.println("Row of " + ServiceName + ":" + DateOfJourney + "is:" + ServiceRow);
System.out.println("Bucket Code column of " + BucketCode + " is: " + BucketCodeColumn);
XLUtils.updateAvailability(ServiceRow, BucketCodeColumn, Available);
}
}
}
}
This is the error I see:
Caused by:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup
failed:
Script1.groovy: 1: unexpected token: [ # line 1, column 27.
restAssuredJsonRootObject.[j].od_pair
Can someone help me please?
I would suggest parsing your JSON into Java classes to ease the processing.
How to do that?
First, we need to create Java classes which will represent the JSON you provided.
Let's analyze the JSON.
Starts with an array. The array contains multiple JSON Object. These objects contain od_pair value and array of objects called buckets.
Let's create a class (you can name it whatever you want) Pair
public class Pair {
public String od_pair; //this name is important because it corresponds with the json element's name!
public List<BucketObject> buckets; //same here!
}
This class represents a single JSON Object in the main Array. It contains od_pair value AND nested JSON Array but in Java representation -> List of BucketObject classes. Let's create BucketObject class:
public class BucketObject { //this name is NOT importnat
public String bucket; //names are important
public int original;
public int available;
}
We have only 3 values in each of the objects.
Now, it's time to parse JSON into the written classes.
JsonPath path = JsonPath.from(json);
Pair[] pairs = path.getObject("$", Pair[].class);
Remember that Pair is a single JSON Object. That's why we start parsing from the root represented by dollar sign $ and we declare that JSON should be parsed into an ARRAY of Pair objects!
Now, processing will be much simpler!
I am not sure what do you need, but I will show you an example of how to get data from the buckets based on od_pair field and you should be able to figure out the rest of the processing.
So, we have the array of Pair class: Pair[] pairs;
Now, we want to get 1 Pair object based on od_pair value.
public static Pair getPairBasedOnOdPairValue(Pair[] pairs, String odPairValue) {
for (Pair pair : pairs) {
if (pair.od_pair.equals(odPairValue)) return pair;
}
throw new NoSuchElementException();
}
Now, we have the Pair object. We can access buckets for this object using
List<BucketObject> buckets = pair.buckets;
The rest of the processing is iterating over List<BucketObject> and getting desired values.
Hope it helps!
OP asked me to advise on how to fix his code, hence the second answer.
Let's analyze the code you provided:
public static void updateBuckets(String ServiceName, String DateOfJourney) throws Exception {
File jsonExample = new File(System.getProperty("user.dir"), "\\LogAvResponse\\LogAvResponse.json");
JsonPath jsonPath = new JsonPath(jsonExample);
List<Object> LegList = jsonPath.getList("$");
// List<HashMap<String, String>> jsonObjectsInArray = jsonPath.getList("$");
int NoofLegs = LegList.size();
System.out.println("No of legs :" + NoofLegs);
for (int j = 0; j <= NoofLegs; j++)
// for (HashMap<String, String> jsonObject : jsonObjectsInArray) {
{
String OD_Pair = jsonPath.param("j", j).getString("[j].od_pair");
// String OD_Pair = jsonObject.get("od_pair");
System.out.println("OD Pair: " + OD_Pair);
List<Object> BucketsList = jsonPath.param("j", j).getList("[j].buckets");
int NoOfBuckets = BucketsList.size();
// System.out.println("OD Pair: " + OD_Pair);
System.out.println("no of Buckets: " + NoOfBuckets);
for (int i = 0; i < NoOfBuckets; i++) {
String BucketCode = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].bucket");
String Available = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].available");
int BucketCodeColumn = XLUtils.getBucketCodeColumn(BucketCode);
int ServiceRow = XLUtils.getServiceRow(ServiceName, DateOfJourney, OD_Pair);
System.out.println("Row of " + ServiceName + ":" + DateOfJourney + "is:" + ServiceRow);
System.out.println("Bucket Code column of " + BucketCode + " is: " + BucketCodeColumn);
XLUtils.updateAvailability(ServiceRow, BucketCodeColumn, Available);
}
}
}
I am not using compilator right now, so I can miss a few things.
#1
First thing I can see is that you save the main array into the List<Object>
List<Object> LegList = jsonPath.getList("$");
Instead, you could save it to more understandable type, since Object is so generic, you have no idea what's inside it.
List<HashMap<String, Object>> LegList = jsonPath.getList("$");
#2
The for loop looks incorrect because of the evaluator
j <= NoofLegs;.
This will probably cause IndexArrayOutOfBoundsException or something similar. With the given code, if you have 4 legs, the for loop will try to process 5 legs which are incorrect.
#3
Similar to the #1, line where you save the bucket list
List<Object> BucketsList = jsonPath.param("j", j).getList("[j].buckets");
Could also be changed to List<HashMap<String, Object>> instead.
If you'd do that, you wouldn't need integer-based nested for loop.
You see, the HashMap<String, Object> is actually crucial to parse nested objects. The String is just a name like buckets or od_pair. It's the JSON representation. The second argument Object is different. RestAssured returns different types within the HashMap, that's why we use Object instead of String. Sometimes it's not String.
Example based on your JSON:
Collect buckets to List of HashMaps:
List<HashMap<String, Object>> bucketsList = jsonPath.param("j", j).getList("[j].buckets");
Each of the HashMap in the list is a representation of this:
{
"bucket":"C00",
"original":2,
"available":2
},
The Object in HashMap is either String or Integer in your case.
So, if you get element bucket from a HashMap you'll get its value.
Let's combine it with for loop for further clarification:
List<HashMap<String, Object>> bucketsList = jsonPath.param("j", j).getList("[j].buckets");
for (HashMap<String, Object> singleBucket : bucketsList) {
String firstValue = (String) singleBucket.get("bucket");
Integer secondValue = (Integer) singleBucket.get("original");
}
Looking at the error message, it looks like you are using rest-assured and that the JsonPath class is io.restassured.path.json.JsonPath from the rest-assured library.
I'm sure you're aware, but (perhaps for other readers) note that this is different from Jayway's json-path and is NOT the com.jayway.jsonpath.JsonPath class from that library.
Also be aware that, as mentioned in the documentation rest-assured uses the Groovy GPath syntax for manipulating/extracting JSON.
With that, I believe the following will extract what you need, i.e. od_pair and their corresponding buckets with available numbers:
Map<String, Map<String, Integer>> map = JsonPath.with(jsonString).get("collectEntries{entry -> [entry.od_pair, entry.buckets.collectEntries{bucketEntry -> [bucketEntry.bucket, bucketEntry.available]}]}");
where for each entry of the map, the key is the od_pair and the value is another map whose key is the bucket and value is the available number. The jsonString is the JSON you provided in the question.
You can iterate through the map to get what you want:
for(Map.Entry<String, Map<String, Integer>> entry : map.entrySet())
{
String od_pair = entry.getKey();
Map<String, Integer> bucketMap = entry.getValue();
for(Map.Entry<String, Integer> bucketEntry : bucketMap.entrySet())
{
String bucket = bucketEntry.getKey();
int available = bucketEntry.getValue();
}
}
Printing out the map you will get:
{7015400:8727100={C00=2, A01=0, B01=480}, 7015400:8814001={C00=2, A01=40, B01=672, B03=632, B05=558}}
Printing the map as JSON using Gson:
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(map));
you will get
{
"7015400:8727100": {
"C00": 2,
"A01": 0,
"B01": 480
},
"7015400:8814001": {
"C00": 2,
"A01": 40,
"B01": 672,
"B03": 632,
"B05": 558
}
}
For background, the String collectEntries{entry -> [entry.od_pair, entry.buckets.collectEntries{bucketEntry -> [bucketEntry.bucket, bucketEntry.available]}]}
is a Groovy closure that uses methods from the Groovy Collections API: Refer Collection, List and Map
Shout out to #Fenio for the pure Java solution above.

Map in Dart is replacing the values of previous keys with the last updated value

I am actually working with maps in Dart and I couldn't figure out why the map variable in my example is behaving strangely or I am doing something wrong in my code.
Please can someone help me to debug the code, I have posted the code to reproduce the issue.
example.dart
void main() {
var data2 = {};
var data1 = {};
var floorDetails = new Map();
floorDetails.clear();
for (int i = 0; i < 2; i++) {
data2.clear();
data1.clear();
for (int j = 0; j < 2; j++) {
data1 = {
'flat${(i + 1) * 100 + (j + 1)}': {'flattype': "flat"},
};
data2.addAll(data1);
}
print('data2=$data2');
floorDetails['floor${(i+1)}'] = data2;
print('floorDetails = $floorDetails');
}
print(floorDetails.keys);
}
The output from the code is:
floorDetails = {
floor1: {
flat201: {flattype: flat},
flat202: {flattype: flat}
},
floor2: {
flat201: {flattype: flat},
flat202: {flattype: flat}
}
}
Actually I was expecting the output to be:
floorDetails = {
floor1: {
flat101: {flattype: flat},
flat102: {flattype: flat}
},
floor2: {
flat201: {flattype: flat},
flat202: {flattype: flat}
}
}
this is actually overwriting the values of all the keys inside the map floorDetails as per documentation for Map.addAll() method
void addAll(
Map<K, V> other
)
Adds all key-value pairs of other to this map.
If a key of other is already in this map, its value is overwritten.
The operation is equivalent to doing this[key] = value for each key and associated value in other. It iterates over other, which must therefore not change during the iteration.
although in the given example the keys are different but it is still overwriting the values.
Please, any help would be much appreciated.
Many Thanks,
Mahi
In the first iteration, here you assign data2
floorDetails['floor${(i+1)}'] = data2;
but the first line in the next iteration is
data2.clear();
which clears data2. This also clears the content of floorDetails['floor1']`, because it references the same map.
Either you create a new map, instead of clearing it by changing
data2.clear();
data1.clear();
to
data2 = {}; // or new Map()
data1 = {};
or create a copy of the map before assigning it
floorDetails['floor${(i+1)}'] = new Map.from(data2);
Map is an object and copied by reference. Only primitive types like bool, double, int, and String are copied by value.

How do I use arrays with Alamofire parameters?

I want send arrays using Alamofire.
What I have
let params: Parameters = [
id:job.id ?? 0,
]
I also have to send array to backend in this format
jobs[0]=1, jobs[1]=2 etc
my key is jobs[0] and value is 1
This is the equlant on Java
for (int i = 0; i < size; i++) {
final int id = job.getPuIds().get(i);
params.put("job" + "[" + i + "]", String.valueOf(id));
}
How could I do this?
Here is an example on how to print the string you want in swift syntax:
for i in 0...jobs.count-1 {
print("job[\(i)]=\(jobs[i].id)")
}
But I think you should try this instead:
Send a dictionary with key "jobs" and the array as the value for that key.
var ids = [Int]()
for job in jobs {
ids.append(job.id)
}
var params = ["jobs":ids]
EDIT: Cleaner code - special thanks to #Alexander
let params = ["jobs": jobs.map{ $0.id }]
Following your implementation in Java, you can do the same in Swift using this:
var params: [String:Any] = [:]
for (index, _) in yourArray.enumerated() {
let id = job.getPuIds()[index]
params["job[\(index)]", "\(id)"]
}
Looking at your implementation I think that I can guess that the size variable is based on what is returned in job.getPuIds(), in this case the code can be simplified:
var params: [String:Any] = [:]
for (index, id) in job.getPuIds().enumerated() {
params["job[\(index)]", "\(id)"]
}

Actionscript: select and display the duplicated value from an array

Please how can I get the duplicated value from an array ?
Ex:
Array [10,3,10,10]
display that we have 3 duplicated in location 1,3 and 4
Regards
I have tried this one :
q = new Array();
q = [A, B, C, D];
qValue = function (array) {
equal = array[0];
for (j=0; j<array.length; j++) {
if (array[j]===equal) {
equal = array[j];
}
}
return equal;
};
trace(qValue(q));
Something like this should work:
var array:Array = [1,2,3,4,3];
// create a dictionary and go through our array pulling out the keys
var dict:Dictionary = new Dictionary();
for each( var i:int in array )
{
if( i in dict ) // checks if the number is already in our dict as a key
dict[i]++;
else
dict[i] = 1;
}
// now go through our dictionary, finding the duplications
for( var key:* in dict )
{
var num:int = dict[key];
if( num == 1 )
continue; // single value - ignore
trace( "We have " + num + " occurrences of " + key );
}
Edit
To also have the locations (indicies) of the repeated values, use this instead:
var array:Array = [1,2,3,4,3];
// create a dictionary and go through our array, pulling out the values
var dict:Dictionary = new Dictionary();
var len:int = array.length;
for( var i:int = 0; i < len; i++ )
{
var val:int = array[i]; // get the value from the array
if( !( val in dict ) ) // if it's not in our dictionary, create a new array
dict[val] = [];
dict[val].push( i ); // add the index of the value to the array
}
// now go through our dictionary, finding the duplications
for( var key:* in dict )
{
var indicies:Array = dict[key];
if( indicies.length <= 1 )
continue; // single value - ignore
trace( "The value " + key + " is repeated " + indicies.length + " times. Indicies: " + indicies );
}
Edit - AS2 no "if in"
Add the function:
function _getArray( obj:Object, val:Number ):Array
{
// try and find the one already created
for( var key:* in obj )
{
if( key == val )
return obj[val];
}
// make a new one
var a:Array = [];
obj[val] = a;
return a;
}
Your array loop should now read
for( var i:int = 0; i < len; i++ )
{
var val:int = array[i]; // get the value from the array
var occurrenceArray = _getArray( obj, val ); // obj = dict
occurrenceArray.push( i ); // add the index of the value to the array
}

Resources