In my scenario I have list of object in C# code and need to be converted into JavaScript object. But there are certain condition, where the value of the object might be dynamic based on certain key.
I have a following method which will return string as JavaScript Object.
public string ItemToJson()
{
List < Item > itemObj = GetItemList();
if (itemObj.Count > 0)
{
StringBuilder sbObj = new StringBuilder();
sbObj.Append("<script> let Items = {");
var len = itemObj.Count;
for (int i = 0; i < len; i++)
{
sbObj.Append(itemObj[i].Key);
sbObj.Append(": { placeholder : \" ");
sbObj.Append(itemObj[i].Placeholder);
sbObj.Append(" \" , value : \" ");
if (itemObj[i].Key == "Photo")
{
sbObj.Append(GetImage());
}
else
{
sbObj.Append(itemObj[i].Value);
}
sbObj.Append(" \" } ");
if (i < len - 1)
sbObj.Append(",");
}
sbObj.Append("} </script>");
return sbObj.ToString();
}
else
{
return string.Empty;
}
}
Here is the complete code of working console app.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace String_Builder_Demo
{
class Program
{
public List<Item> GetItemList()
{
List<Item> items = new List<Item>
{
new Item(){ Key = "FirstName", Placeholder = "##FirstName##", Value="John" },
new Item(){ Key = "LastName", Placeholder = "##LastName##", Value="Doe"},
new Item(){ Key = "Email", Placeholder = "##Email##", Value="[email protected] " },
new Item(){ Key = "Address", Placeholder = "##Address##", Value="Kathmandu" },
new Item(){ Key = "Photo", Placeholder = "##Photo##", Value=""}
};
return items;
}
public string GetImage()
{
return "http://via.placeholder.com/350x150";
}
static void Main(string[] args)
{
Program obj = new Program();
Console.WriteLine(obj.ItemToJson());
Console.ReadLine();
}
public string ItemToJson()
{
List<Item> itemObj = GetItemList();
if (itemObj.Count > 0)
{
StringBuilder sbObj = new StringBuilder();
sbObj.Append("<script> let Items = {");
var len = itemObj.Count;
for (int i = 0; i < len; i++)
{
sbObj.Append(itemObj[i].Key);
sbObj.Append(": { placeholder : \" ");
sbObj.Append(itemObj[i].Placeholder);
sbObj.Append(" \" , value : \" ");
if (itemObj[i].Key == "Photo")
{
sbObj.Append(GetImage());
}
else
{
sbObj.Append(itemObj[i].Value);
}
sbObj.Append(" \" } ");
if (i < len - 1)
sbObj.Append(",");
}
sbObj.Append("} </script>");
return sbObj.ToString();
}
else
{
return string.Empty;
}
}
}
public class Item
{
public string Placeholder { get; set; }
public string Value { get; set; }
public string Key { get; set; }
}
}
The above mention code will return following string.
<script>
let Items = {
FirstName:
{
placeholder: " ##FirstName## ",
value: " John "
},
LastName:
{
placeholder: " ##LastName## ",
value: " Doe "
},
Email:
{
placeholder: " ##Email## ",
value: " [email protected] "
},
Address:
{
placeholder: " ##Address## ",
value: " Kathmandu "
},
Photo:
{
placeholder: " ##Photo## ",
value: " http://via.placeholder.com/350x150 "
}
}
</script>
How can I optimize the above code and eliminate the if else
condition from ItemToJson()
method?
3 Answers 3
This is a bit off topic... but unless you are pushing a lot of data through this, StringBuilder isn't going to save you much.
Probably worth profiling to see. If you don't need it, then you can make the code pretty simple.
public string ItemToJson()
{
List<Item> itemObj = GetItemList();
if ( itemObj.Count <= 0 )
{
return string.Empty;
}
var parts = itemObj.Select (
( item ) =>
{
var val = item.Key == "Photo" ? GetImage () : item.Value;
return $"{item.Key}: {{ placeholder : \" {item.Placeholder} \" , value : \" {val} \" }} ";
} );
var json = string.Join ( "," , parts);
return $"<script> let Items = {{{json}}} </script>";
}
-
\$\begingroup\$ You have very unusual code formatting... spaces everywhere :-o \$\endgroup\$t3chb0t– t3chb0t2018年07月17日 16:09:21 +00:00Commented Jul 17, 2018 at 16:09
-
1\$\begingroup\$ Many years ago, monks found copying books really hard, so they started adding spaces between the words to make it easier to keep track of where you were upto. This caught on as it makes reading the text easlier. One day I hope developers will have the same epiphany. :P \$\endgroup\$Nigel Thorne– Nigel Thorne2018年07月18日 05:05:22 +00:00Commented Jul 18, 2018 at 5:05
-
\$\begingroup\$ @NigelThorne: hah, I do the same, but not as much as you :P (spaces before
(
in method calls, and method definitions) \$\endgroup\$apocalypse– apocalypse2018年07月18日 15:54:13 +00:00Commented Jul 18, 2018 at 15:54 -
\$\begingroup\$ @apocalypse I was playing with Resharper settings... :) I'm not sure I'll keep all of them going forward but I do think in general developers don't use enough whitespace. \$\endgroup\$Nigel Thorne– Nigel Thorne2018年07月18日 23:31:28 +00:00Commented Jul 18, 2018 at 23:31
I'd recommend using a library for something like this. Formatting JSON manually difficult and error prone. Json.NET is nice and straight forward in this case.
public string ItemToJson()
{
var result = new JObject();
foreach (var property in GetItemList())
{
result.Add(property.Key, new JObject
{
["placeholder"] = property.Placeholder,
["value"] = property.Key != "Photo"
? property.Value
: "http://via.placeholder.com/350x150"
});
}
return $"<script>let Items = {JsonConvert.SerializeObject(result)};</script>";
}
Had to put it here as it was getting too big for comment.
You definitely need to evaluate that condition based on code you have posted. So, the if/else construct is fine. Alternate options will need you to split the list into separate ones which will be more costly operations.
If I really have to nitpick, I would change the key
datatype to int
or add another property in Item
class itself which is a bool
. Perhaps something of is this sort:
class Item
{
private string _key;
public string Key
{
get
{
return _key;
}
set
{
_key = value;
IsPhoto = (string.Compare(value, "Photo", true) == 0);
}
}
public bool IsPhoto
{
get;
set;
}
}
This will remove the string comparison in loop and move it to object creation/update action.
##Photo##
so I thing its impossible to use json.net \$\endgroup\$if else
in this case ? \$\endgroup\$if/else
statement? What's wrong with it? \$\endgroup\$