two list to json in c# - arrays

I have three list in format below and I want to convert this to json format. length of list in all data sample are same.
List<string> data1=new List<string>{"col1","Col2","Col3",...}
List<string> data2=new List<string>{"a","b","c"...}
List<string> data3=new List<string>{"d","e","f"...}
I want to convert this data into json format where data1 is always to be key and other list to be value. I am expecting output something like
COnvertedSon = [{"col1":"a","col2":"b","col3":"c",....},
{"col1":"d","col2":"e","col3":"f"....}]

This should work for you:
List<string> data1 = new List<string> {"col1", "Col2", "Col3"};
List<string> data2 = new List<string> {"a", "b", "c"};
List<string> data3 = new List<string> {"d", "e", "f"};
List<dynamic> list = new List<dynamic>();
var item1 = new ExpandoObject() as IDictionary<string, Object>;
var item2 = new ExpandoObject() as IDictionary<string, Object>;
foreach (var item in data1)
{
item1.Add(item, string.Empty);
item2.Add(item, string.Empty);
}
var keys = item1.Keys.ToArray();
for (int i = 0; i < keys.Length; i++)
{
var key = keys[i];
item1[key] = data2.ElementAt(i);
item2[key] = data3.ElementAt(i);
}
list.Add(item1);
list.Add(item2);
var result = JsonConvert.SerializeObject(list);
This doesn't include any error or null checking whatsoever and assumes that the lenghts of all Lists is the same.

Try by using the following code
var json = JsonConvert.SerializeObject(list,
Formatting.None,
new JsonSerializerSettings()
{
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});

Related

Change List<Object> into List<List<int>> using LINQ

I have an application using the following model:
namespace myapp.Models.Types
{
public class PressureRowT
{
public System.DateTime Timestamp { get; set; }
public int P1{ get; set; }
public int P2{ get; set; }
public int P3{ get; set; }
public int P4{ get; set; }
public int P5{ get; set; }
}
}
I have a List< PressureRowT > with approximately 5000 elements, generated by parsing files. I need to plot the pressure by passing the data to chart.js for data viewing. For that, I would need a JSON array like:
[Timestamp: [date1, date2, date3... daten], P1: [val1, val2, val3, ..., valn], P2: [val1, val2, val3, ..., valn] ... P5: [val1, val2, val3, ..., valn]]
What would be the most efficient way of "inverting" the structure ?
Thank you in advance.
Assuming right now you have a list of PressureRowT and you want an object PressureRowT with lists within it, you can use something like
var Timestamps = pressureRowTList.Select(pressureRowT => pressureRowT.TimeStamp).ToList();
for each of the fields and assign them all to one object.
The most efficient way would be to re-write your parsing code to build the correct structures as the files are read.
Barring that, the best thing to do is not use LINQ, but simply build the Lists needed. A for loop is more efficient than a foreach when processing a List:
var src = new List<PressureRowT>();
var srccount = src.Count;
var PR_TS = new List<DateTime>(srccount);
var PR_P1 = new List<int>(srccount);
var PR_P2 = new List<int>(srccount);
var PR_P3 = new List<int>(srccount);
var PR_P4 = new List<int>(srccount);
var PR_P5 = new List<int>(srccount);
for (int j1 = 0; j1 < srccount; ++j1) {
PR_TS.Add(src[j1].Timestamp);
PR_P1.Add(src[j1].P1);
PR_P2.Add(src[j1].P2);
PR_P3.Add(src[j1].P3);
PR_P4.Add(src[j1].P4);
PR_P5.Add(src[j1].P5);
}
var ans = new { Timestamp = PR_TS, P1 = PR_P1, P2 = PR_P2, P3 = PR_P3, P4 = PR_P4, P5 = PR_P5 };
I might use Aggregate to build up the result object:
IEnumerable<PressureRowT> values;
var resultSeed = new {
Timestamp = new List<DateTime>(),
P1 = new List<int>(),
P2 = new List<int>(),
P3 = new List<int>(),
P4 = new List<int>(),
P5 = new List<int>(),
};
return values.Aggregate(
resultSeed,
(result, value) => {
result.Timestamp.Add(value.Timestamp);
result.P1.Add(value.P1);
result.P2.Add(value.P2);
result.P3.Add(value.P3);
result.P4.Add(value.P4);
result.P5.Add(value.P5);
return result;
});

Split the string array

I know this question was absolutely answered but i did not find solution.
I get response from web-service a Json string response that is ["11,22222","33,44444"].
I try this but did not work because string include these characters [ ] and first comma is in the here 11,22
StringBuilder result = new StringBuilder();
URL url2 = new URL(url);
HttpURLConnection conn = (HttpURLConnection) url2.openConnection();
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
String res = new String(result);
String [] coordinates = res.split(",");
How can i separate this string like "11,22222" and "33,44444"
Just use JavaScriptSerializer.
public void Method(string json)
{
JavaScriptSerializer js = new JavaScriptSerializer();
List<string> results = js.Deserialize<List<string>>(json);
}
JsonArray jArray=new JsonArray(result);
StringBuffer s=new StringBuffer();
for(int i=0;i<jArray.length();i++)
{
s.append(jArray.getString(i));
Log.e(“singleValue”,jArray.getString(i));
}
Log.e(“responsed”,s.toString());
Since you are getting a json, you can easily convert it to JsonArray and iterate thorugh it.
Gson gson = new Gson();
JsonArray array = gson.fromJson(rd, JsonElement.class).getAsJsonArray();
for (JsonElement jsonElement : array) {
System.out.println(jsonElement.getAsString());
}
Hope this helps.

Basically I have a data grid view in windows form. And I have added a combo box as a column

This is my object structure
class object
{
string projectname;
string projectid;
list<string> associated_students;
}
//The List I am binding to the grid
list<objects> objectList = getList();
dataGridView.Source =objectList;
Now I want to bind the combo box inside the datagrid with the list "associated_students"
If I understand the question, you want each row to be tied to an object within your list of objects and you want the third column to show a combobox of that object's unique list of associated students. If I am correct, a simple search leads to this similar question:
How do I set up a DataGridView ComboBoxColumn with a different DataSource in each cell?
To solve, you need to manually bind each row. I was able to duplicate your problem and came up with this solution:
Your class "object"
public class Assignment
{
public Assignment()
{
this.Associated_Students = new List<string>();
}
public string ProjectName { get; set; }
public string ProjectID { get; set; }
public List<string> Associated_Students { get; set; }
}
And in Form1:
public Form1()
{
InitializeComponent();
this.Assignments = new List<Assignment>()
{
new Assignment()
{
ProjectID = "1",
ProjectName = "First",
Associated_Students = new List<string>() { "Me", "You", "Him", "Her" }
},
new Assignment()
{
ProjectID = "2",
ProjectName = "Second",
Associated_Students = new List<string>() { "Foo", "Bar" }
}
};
this.BindDGViewToList();
}
public List<Assignment> Assignments { get; set; }
public void BindDGViewToList()
{
DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.Name = "Project Name";
col1.ValueType = typeof(string);
dataGridView1.Columns.Add(col1);
DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn();
col2.Name = "Project ID";
col2.ValueType = typeof(string);
dataGridView1.Columns.Add(col2);
DataGridViewComboBoxColumn col3 = new DataGridViewComboBoxColumn();
col3.Name = "Associated Students";
col3.ValueType = typeof(string);
dataGridView1.Columns.Add(col3);
for (int i = 0; i < this.Assignments.Count; i++)
{
DataGridViewRow row = (DataGridViewRow)(dataGridView1.Rows[0].Clone());
DataGridViewTextBoxCell textCell = (DataGridViewTextBoxCell)(row.Cells[0]);
textCell.ValueType = typeof(string);
textCell.Value = this.Assignments[i].ProjectName;
textCell = (DataGridViewTextBoxCell)(row.Cells[1]);
textCell.ValueType = typeof(string);
textCell.Value = this.Assignments[i].ProjectID;
DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)(row.Cells[2]);
comboCell.ValueType = typeof(string);
comboCell.DataSource = this.Assignments[i].Associated_Students;
dataGridView1.Rows.Add(row);
}
}
Note: This will display what you are asking for but you will have to handle updating your data. I would suggest researching BindingList over List objects. There may be better solutions, but this worked quickly for me.

pick any string to display in a text box in EF

Using Entity framework how can I pick any string to display in a textbox. Using myReader in the past I would do the following:
while (myReader.Read())
{
string sName = myReader.GetString(1);
txtName.Text = sName;
}
You have to load the entity (=table) you desire and than assign the property of the entity to the textbox.
Something like:
using (var myContext = new EntityContext())
{
myContext.TableName.Load(); //this will load all rows from the table
var list = myContext.TableName.Local; //.Local is a list of the entities which gets populated when you cann the Load() method
//now you can either enumarte your list like so
foreach (TableName item in list)
{
string sName = item.PropertyName; //PropertyName is the property you want to display, this would be like using not an index in myReader.GetString(1) but the columnname myReader.GetString("ColumnName")
txtName.Text = sName;
}
//or if you want to get a certain item out of your list you can use LINQ/MethodChains
//MethodChain
var item = list.First(x => x.PropertyName == "HelloWorld!");
string sName = item.PropertyName;
txtName.Text = sName;
//LINQ
var item = (from x in list
where x.PropertyName == "HelloWorld!"
select x).First();
string sName = item.PropertyName;
txtName.Text = sName;
//the methodchain and linq is a "new" technology that simplifies this code (which does the same)
TableName item = null;
foreach (TableName tempItem in list)
{
if (tempItem.PropertyName == "HelloWorld!")
{
item = tempItem;
break;
}
}
string sName = item.PropertyName;
txtName.Text = sName;
}

accessing array properties

var questions:Array = new Array;
questions[0] = "qname:mc_01, qvalue:1";
questions[1] = "qname:mc_02, qvalue:1";
questions[2] = "qname:mc_03, qvalue:1";
questions[3] = "qname:mc_04, qvalue:1";
questions[4] = "qname:mc_05, qvalue:1";
questions[5] = "qname:mc_06, qvalue:1";
questions[6] = "qname:mc_07, qvalue:1";
questions[7] = "qname:mc_08, qvalue:1";
questions[8] = "qname:mc_09, qvalue:1";
questions[9] = "qname:mc_10, qvalue:1";
questions[10] = "qname:mc_11, qvalue:2";
questions[11] = "qname:mc_12, qvalue:2";
questions[12] = "qname:mc_13, qvalue:2";
questions[13] = "qname:mc_14, qvalue:2";
questions[14] = "qname:mc_15, qvalue:2";
questions[15] = "qname:mc_16, qvalue:2";
questions[16] = "qname:mc_17, qvalue:2";
questions[17] = "qname:mc_18, qvalue:2";
questions[18] = "qname:mc_19, qvalue:2";
questions[19] = "qname:mc_20, qvalue:2";
questions[20] = "qname:mc_21, qvalue:3";
questions[21] = "qname:mc_22, qvalue:3";
questions[22] = "qname:mc_23, qvalue:3";
questions[23] = "qname:mc_24, qvalue:3";
questions[24] = "qname:mc_25, qvalue:3";
questions[25] = "qname:mc_26, qvalue:3";
questions[26] = "qname:mc_27, qvalue:3";
questions[27] = "qname:mc_28, qvalue:3";
questions[28] = "qname:mc_29, qvalue:3";
questions[29] = "qname:mc_30, qvalue:3";
I've got this array and want to access the qname property and can't remember how to do it. Is it something like questions[0].qname or questions[0](qname)?
You've defined your array elements as string instead of objects.
Try this instead:
var questions:Array = new Array;
questions[0] = {qname:mc_01, qvalue:1};
...
Curly braces instead of double-quotation marks. With quotation marks you create strings. With curly braces, you can create dynamic objects and set their properties. So if you are creating a string value for qname, make sure you define it as qname:"mc_01" instead of qname:mc_01.
So you can use questions[0].qname or questions[0]["qname"] to access the properties.
But if you can't do that what is told in previous answer (e.g. you get those strings from server) you can use regular expresions to get those values nicely:
var searchPattern : RegExp = /(?P<qname>(?<=qname\:)[a-zA-Z0-9_]+(?=[\s,]*))/g;
trace( searchPattern.exec(questions[1]).qname ); // traces out: mc_02
As you tagged ActionScript 3.0, and its a strongly typed language, I would recommend a typed class to hold your data structure.
package your.package.name
{
public class Question
{
protected var _name:String;
protected var _value:String;
public function Question(name:String = null, value:String = null)
{
this.name = name;
this.value = value;
}
public function get name():String
{
return _name;
}
public function set name(value:String):void
{
_name = value;
}
public function get value():String
{
return _value;
}
public function set value(value:String):void
{
_value = value;
}
}
}
By having getters and setters and also exposing these props in the constructor you can create them in two ways:
var question:Question = new Question("Question1", "Question value");
OR:
var question:Question = new Question();
question.name = "Question1";
question.value = "Question value";
This offers benefits in terms of intellisense for getting properties in your ide and also type safety to stop you putting in incorrect types for name and value.
Then to get hold of a question:
questions[0].name; // in this example Question1
questions[0].value; // in this example Question value
Usually your questions would be coming from some data source, like xml or a web service, whatever I'll use literal xml for this example, in that scenario you would want to build your objects in some loop eg:
var questionsXML:XML =
<questions>
<question name="Question1">Question1 value</question>
<question name="Question2">Question2 value</question>
<question name="Question3">Question3 value</question>
</questions>
Then:
var questions:Array = [];
for each (var questionXML:XML in questionsXML.question)
{
var question:Question = new Question();
question.name = questionXML.#name;
question.value = questionXML.text();
questions.push(question);
}

Resources