Related
please check out this fiddle.
This has an outerHTML var. Now, I have to create it as a list of objects ; objects will be each row.
In this example the row number is 3 , but I will get it in a var like
var maxrow = $('#rownumber').val();
var TotalObject = [] ;
that will contain :
{
{column1header :row1col1value ,column2header :row1col2value ,column3header :row1col3value,column4header :row1col4value },
{column1header :row2col1value ,column2header :row2col2value ,column3header :row2col3value,column4header :row2col4value },
{column1header :row2col1value ,column2header :row2col2value ,column3header :row2col3value,column4header :row2col4value }
}
Then, I have to send this list of objects to my controller action method with an ajax call :
[httppost]
public PartialViewResult MyAction(list<mymodel> model)
{
return Partialview ("mypartialview",model);
}
mymodel also has IEnumerable<mymodel> where I have to transform this to that.
How about this approach :
Clean the input with a regular expression
Split it into an array
Create an iterator for your data
Push the result into a JSON object
Send the JSON result with Ajax?
EDIT: I improved the cleanup regular expressions ; it should account for empty values now.
It is based on the HTML markup, which isn't valid in your example (missing </tr> or <tr> tags).
var outerhtml = "\r\n\r\n<thead>\r\n\r\n<tr>\r\n\r\n<th>\r\n\r\ncolumn1header\r\n\r\n\r\n\r\n</th>\r\n\r\n<th>\r\n\r\ncolumn2header\r\n\r\n</th>\r\n\r\n<th>\r\n\r\ncolumn3header\r\n\r\n</th>\r\n\r\n<th>\r\n\r\ncolumn4header\r\n\r\n</th>\r\n\r\n</tr>\r\n\r\n</thead>\r\n\r\n<tbody>\r\n\r\n<tr>\r\n\r\n<td>\r\n\r\nrow1col1value\r\n\r\n</td>\r\n\r\n<td>\r\n\r\nrow1col2value\r\n\r\n</td>\r\n\r\n<td>\r\n\r\nrow1col3value\r\n\r\n</td>\r\n\r\n<td>\r\n\r\nrow1col1value\r\n\r\n</td>\r\n\r\n</tr>\r\n\r\n<tr>\r\n\r\n<td>\r\n\r\nrow2col1value\r\n\r\n</td>\r\n\r\n<td>\r\n\r\nrow2col2value\r\n\r\n</td>\r\n\r\n<td>\r\n\r\nrow2col3value</td>\r\n\r\n<td>\r\n\r\nrow2col4value\r\n\r\n</td>\r\n\r\n</tr>\r\n\r\n<td>\r\n\r\nrow3col1value\r\n\r\n</td>\r\n\r\n<td>\r\n\r\n row3col2value\r\n\r\n </td>\r\n\r\n<td>\r\n\r\nrow3col3value\r\n\r\n</td>\r\n\r\n <td>\r\n\r\n row3col4value \r\n\r\n </td>\r\n\r\n</tbody>\r\n\r\n";
const data = outerhtml.split("\r\n").join("");
const [_,h,v] = /(?:<thead><tr>(.*)<\/tr><\/thead>)(?:<tbody>(.*)<\/tbody>)/igm.exec(data);
const headers = h.split("</th><th>")
.map(t => t.replace("<th>","")
.replace("</th>",""));
const values = v.match(/(?:<td>\s*(\s*\w*)\s*<\/td>)/igm)
.map(t => t.replace("<td>","")
.replace("</td>","")
.trim());
const iterator = function(array){
const coll = [...array];
return {
[Symbol.iterator](){
let nextIndex = 0;
return {
next: function(){
const _r = {
[headers[0]] : coll[nextIndex],
[headers[1]] : coll[nextIndex+1],
[headers[2]] : coll[nextIndex+2],
[headers[3]] : coll[nextIndex+3]
};
nextIndex += 4;
return nextIndex <= coll.length ?
{value: _r, done: false} :
{done: true};
}
}
}
}
}
let json=[];
const tuples = iterator(values);
for(tuple of tuples){
json.push(tuple);
}
console.log(json);
I have a bunch of log data which is stored in a variable. Each log value contains a camera name and system ip. I want to create an object which has names as all the distinct system ip's and corresponding value as an array which contains all the camera names corresponding to that system ip. Below is my code ---
$http(req).success(function(data){
$scope.logs = data;
$scope.cameras={};
var v =$scope.logs[0].systemIp;
$scope.cameras["v"]=[];
$scope.cameras["v"].push($scope.logs[0].cameraName);
for(i=1;i<$scope.logs.length;i++){
v=$scope.logs[i].systemIp;
var flag=0;
for(j in $scope.cameras){
if(j==="v")
{
flag=1;
break;
}
}
if(flag==0)
{
$scope.cameras["j"]=[];
$scope.cameras["j"].push($scope.logs[i].cameraName);
}
else if(flag==1)
{
$scope.cameras["v"].push($scope.logs[i].cameraName);
}
}});
And this is what my data looks like --
[{
"_id": "57683fd82c77bb5a1a49a2aa",
"cameraIp": "192.16.0.9",
"cameraName": "garage2",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f8e2c77bb5a1a49a2a9",
"cameraIp": "192.16.0.8",
"cameraName": "garage1",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f5e2c77bb5a1a49a2a8",
"cameraIp": "192.16.0.7",
"cameraName": "Back Door",
"systemIp": "192.168.0.4"
}]
When I print $scope.cameras on my console it gives this as the output -
Object { v: Array[3] }
I want by cameras object to look like this --
{ "192.168.0.2" : [ "garage1" , "garage2"] ,
"192.168.0.4" : [ "Back Door"] }
I am new to javascript, any help is appreciated.
If you are using the Lodash or Underscore library (which I highly recommend), you can just use the _.groupBy() function to do what you are after (along with some other functions to ensure all values are unique).
However, you can also easily implement it yourself:
function groupByDistinct(arr, prop, mapFn) {
mapFn = mapFn || function (x) { return x; };
var output = {};
arr.forEach(function (item) {
var key = item[prop],
val = mapFn(item);
if (!output[key]) {
output[key] = [val];
return;
}
if (output[key].indexOf(val) < 0) {
output[key].push(val);
}
});
return output;
}
Use it for your code like so:
$scope.cameras = groupByDistinct(data, 'cameraIp', function (logEntry) {
return logEntry.cameraName;
});
You are passing a string such as "v" or "j" as your object key, and this string are actually ending being your object key and not the value of this variables as you want. You can use something like this:
for(i=0; i < $scope.logs.length; i++){
var _sysIp = $scope.logs[i].systemIp,
_camName = $scope.logs[i].cameraName;
if(!$scope.cameras.hasOwnProperty(_sysIp)) {
$scope.cameras[_sysIp] = [_camName];
} else if ($scope.cameras[_sysIp].indexOf(_camName) < 0) {
$scope.cameras[_sysIp].push(_camName);
}
}
I'm struggling on adding an Object to an Array (E-commerce context).
My "tc_vars" datalayer is mapped with another datalayer which is called "wa_data". The latter sends the requested information to the first one.
An Object in that case will be a specific product and the Array will be the cart.content property :
var tc_vars = {
nav : {
siteCategory : wa_data.nav.siteCategory,
environment :wa_data.nav.environment,
siteType :wa_data.nav.siteType,
siteName :wa_data.nav.siteName,
pageName :wa_data.nav.pageName,
siteSection :wa_data.nav.siteSection,
country :wa_data.nav.country,
language :wa_data.nav.language,
template :wa_data.nav.template,
doNotTrack :window.navigator.doNotTrack,
customReferrer :wa_data.nav.customReferrer,
genomeID :wa_data.nav.genomeID,
mdmBID :wa_data.nav.mdmBID,
mdmIID :wa_data.nav.mdmIID
},
profile : {
uplayID : readCookie("user_id"),
loginStatus : ''
},
internalSearch : {
searchStatus :wa_data.internalSearch.searchStatus,
searchFilters :wa_data.internalSearch.searchFilters,
searchKeyWord :wa_data.internalSearch.searchKeyWord,
totalResults :wa_data.internalSearch.totalResults,
resultPosition :wa_data.internalSearch.resultPosition,
autoCompletion :wa_data.internalSearch.autoCompletion
},
product : {
productID :wa_data.product.productID,
unitSalePrice :wa_data.product.unitSalePrice,
salePrice :wa_data.product.salePrice,
stockAvailability :wa_data.product.stockAvailability,
salesType :wa_data.product.salesType,
costOfGood :wa_data.product.costOfGood
},
cart : {
orderID:wa_data.cart.orderID,
cartOpen:wa_data.cart.cartOpen,
cartAdd:wa_data.cart.cartAdd,
cartRemove:wa_data.cart.cartRemove,
cartView:wa_data.cart.cartView,
checkout:wa_data.cart.checkout,
purchase:wa_data.cart.purchase,
currency:wa_data.cart.currency,
paymentMethod:wa_data.cart.paymentMethod,
orderShipping:wa_data.cart.orderShipping,
orderTotalAmountDiscounted:wa_data.cart.orderTotalAmountDiscounted,
orderTotalAmountNotDiscounted:wa_data.cart.orderTotalAmountNotDiscounted,
orderTaxAmount:wa_data.cart.orderTaxAmount,
orderDiscountedAmount:wa_data.cart.orderDiscountedAmount,
orderShippingCost:wa_data.cart.orderShippingCost,
billingRegion:wa_data.cart.billingRegion,
billingCity:wa_data.cart.billingCity,
orderStatus:wa_data.cart.orderStatus,
content : [{
productID:'',
name:'',
quantity :'',
promoCode:'',
offerID:'',
salesType:'',
platform :'',
unitSalePrice:'',
salePrice:'',
stockAvailability:'',
lineItemTotalAmountDiscounted:'',
lineItemTotalAmountNotDiscounted:'',
lineItemTaxAmount:'',
lineItemDiscountedAmount:'',
lineItemShippingCost:'',
crossSell:'',
upSell:''
}]
},
tech : {
containerVersion : wa_data.tech.containerVersion
}
}
//Scanning for the content using a loop
if (typeof tc_vars.cart.content !== 'undefined' && tc_vars.nav.pageName === 'Basket'){
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content[i].productID = wa_data.cart.content[i].productID;
tc_vars.cart.content[i].name = wa_data.cart.content[i].name;
tc_vars.cart.content[i].quantity = wa_data.cart.content[i].quantity;
tc_vars.cart.content[i].promoCode = wa_data.cart.content[i].promoCode;
tc_vars.cart.content[i].offerID = wa_data.cart.content[i].offerID;
tc_vars.cart.content[i].salesType = wa_data.cart.content[i].salesType;
tc_vars.cart.content[i].platform = wa_data.cart.content[i].platform;
tc_vars.cart.content[i].unitSalePrice = wa_data.cart.content[i].unitSalePrice;
tc_vars.cart.content[i].salePrice = wa_data.cart.content[i].salePrice;
tc_vars.cart.content[i].stockAvailability = wa_data.cart.content[i].stockAvailability;
tc_vars.cart.content[i].lineItemTotalAmountDiscounted = wa_data.cart.content[i].lineItemTotalAmountDiscounted;
tc_vars.cart.content[i].lineItemTotalAmountNotDiscounted = wa_data.cart.content[i].lineItemTotalAmountNotDiscounted;
tc_vars.cart.content[i].lineItemTaxAmount = wa_data.cart.content[i].lineItemTaxAmount;
tc_vars.cart.content[i].lineItemDiscountedAmount = wa_data.cart.content[i].lineItemDiscountedAmount;
tc_vars.cart.content[i].lineItemShippingCost = wa_data.cart.content[i].lineItemShippingCost;
tc_vars.cart.content[i].crossSell = wa_data.cart.content[i].crossSell;
tc_vars.cart.content[i].upSell = wa_data.cart.content[i].upSell;
}
}
The problem I'm facing here is that my code is not creating a new object for each new product that is added to the cart content (with all the dedicated properties of the new object).
I've tried using a loop which scans my cart content Array but apparently it's not working (not adding a new object inside the Array). Seems like I'm missing something.
Do you guys have any ideas?
Thx a lot
J
tc_vars.cart.content[i] is undefined. You need to define it first, before filling it up.
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content[i] = {}; // Creates an empty object
tc_vars.cart.content[i].productID = wa_data.cart.content[i].productID; // Starts filling it
// ....
}
As an alternative (lighter syntax and faster execution), you could also write :
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content[i] = {
productID : wa_data.cart.content[i].productID,
name : wa_data.cart.content[i].name,
// ....
}
}
But we don't usually add things to an Array by its index. We just push things into it :
for(i=0; i < tc_vars.cart.content.length; i++) {
tc_vars.cart.content.push({
productID : wa_data.cart.content[i].productID,
name : wa_data.cart.content[i].name,
// ....
});
}
This being said, it looks like all you're doing here is copying (not instanciating) wa_data.cart.content into tc_vars.cart.content. So you can completely forget my answer and replace your whole for loop with Gurvinder's answer (+1'd him):
tc_vars.cart.content = JSON.parse(JSON.stringify(wa_data.cart.content));
Unless wa_data already have objects repeated at all the index, following code should work
tc_vars.cart.content = JSON.parse(JSON.stringify(wa_data.cart.content));
You can use an object literal:
tc_vars.cart.content[i] = {
productID: wa_data.cart.content[i].productID,
name: wa_data.cart.content[i].name,
quantity: wa_data.cart.content[i].quantity,
promoCode: wa_data.cart.content[i].promoCode,
offerID: wa_data.cart.content[i].offerID,
salesType: wa_data.cart.content[i].salesType,
platform: wa_data.cart.content[i].platform,
unitSalePrice: wa_data.cart.content[i].unitSalePrice,
salePrice: wa_data.cart.content[i].salePrice,
stockAvailability: wa_data.cart.content[i].stockAvailability,
lineItemTotalAmountDiscounted: wa_data.cart.content[i].lineItemTotalAmountDiscounted,
lineItemTotalAmountNotDiscounted: wa_data.cart.content[i].lineItemTotalAmountNotDiscounted,
lineItemTaxAmount: wa_data.cart.content[i].lineItemTaxAmount,
lineItemDiscountedAmount: wa_data.cart.content[i].lineItemDiscountedAmount,
lineItemShippingCost: wa_data.cart.content[i].lineItemShippingCost,
crossSell: wa_data.cart.content[i].crossSell,
upSell: wa_data.cart.content[i].upSell
}
I have a JSON object like this...
{
"tasks":[
{
"id":"task_3",
"taskName":"Task A",
"assignee":"Barrack Obama",
"timeReqOptimisitic":"4",
"timeReqNormal":"8",
"timeReqPessimistic":"14",
"timeUnit":"Days",
"timeReq":"8.33",
"positionX":493,
"positionY":101,
"lockStatus":"unlocked"
}
],
"milestones":[
{
"id":"task_1",
"milestoneName":"Start",
"positionX":149,
"positionY":109,
"lockStatus":"unlocked",
"milestoneDate":"2015-04-07"
},
{
"id":"task_2",
"milestoneName":"Finish",
"positionX":989,
"positionY":367,
"lockStatus":"unlocked",
"milestoneDate":"2015-04-22"
}
],
"connections":[
{
"connectionId":"con_10",
"pageSourceId":"task_1",
"pageTargetId":"task_3"
},
{
"connectionId":"con_20",
"pageSourceId":"task_3",
"pageTargetId":"task_2"
}
]
}
...this is a minimal version. In practice, there are numerous items in "tasks", "milestones" and "connections".
I need to iterate through the object and determine the "id" of the "milestones" item with the lowest/earliest "milestoneDate", then identify the "connections" item that has the same value for its "pageSourceId" and return its "pageTargetId".
So in the above example:
Step 1) Iterate through the object and determine the "id" of the "milestones" item with the lowest/earliest "milestoneDate".
Answer: milestones.id = "task_1"
Step 2) Identify the "connections" item that has the same value for its "pageSourceId".
Answer: connections.pageSourceId = "task_1"
Step 3) Return its "pageTargetId".
Answer: "task_3"
I have a working example here. However, I would like to know if there is a way to accomplish this without using the extremely high start date and also in one loop.
As you are not parsing the same array on these two loops, there is no way to merge your loops.
Anyway, you can yet remove the loops to access to the arrays:
http://jsfiddle.net/gael/sruvtwre/2/
$.each(object.milestones, function( index, value ) {
if(startDate > parseDate(value.milestoneDate)) {
startDate = parseDate(value.milestoneDate);
id = value.id
}
});
$.each(object.connections, function( index, value ) {
if(id == value.pageSourceId) {
pageTargetId = value.pageTargetId;
}
});
May be also sorting, and indexing your datas. Then you would need no loops:
Elements in milestones should be sorted, so the earliest milestones element would be milestones[0].
Elements in connections should be indexed by their pageTargetId property, so the requested element should be connections[id].
Your two loops would become:
var pageTargetId= object.connections[ object.milestones[0].id ].pageTargetId;
http://jsfiddle.net/gael/sruvtwre/4/
As said in comments, sorting is not an optimal solution, even if that does not really matter for small sets.
Roughly, there is no no needs to sort all the datas, just the latest matters.
You can use array reduce method, as an comparable alternative to a simple loop:
var latestMilestone= object.milestones.reduce(function(milestone1, milestone2){
if( parseDate(milestone1.milestoneDate) > parseDate(milestone2.milestoneDate) )
return milestone1;
else
return milestone2;
//convert date to timestamp
function parseDate(date) {
var parts = date.split('-');
return Date.UTC(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}
});
How about this:
Assuming you get the milestones.id = "task_1" in first loop; outside the loop we can have use jQuery grep. As connections will have unique pageSourceId, grep will return an array with only one object.
var filteredData = jQuery.grep('CONNECTIONS_ARRAY', function(element, index){
return element.pageSourceId == 'MILESTONES_ID'; // Which you get in the loop earlier
});
Then we can access pageTargetId like this:
if(filteredData.length){
filteredData[0].pageTargetId;
}
Try
var dates = []
, ids = []
, filtered = $.map(data.milestones, function(value, index) {
dates.push(new Date(value.milestoneDate).getTime());
ids.push(value.id);
if (dates.length === data.milestones.length) {
var id = ids[$.inArray(Math.min.apply(Math, dates), dates)]
, res = $.grep(data.connections, function(task, key) {
return task.pageSourceId === id
})[0].pageTargetId;
return res
}
})[0]; // `"task_3"`
var data = {
"tasks":[
{
"id":"task_3",
"taskName":"Task A",
"assignee":"Barrack Obama",
"timeReqOptimisitic":"4",
"timeReqNormal":"8",
"timeReqPessimistic":"14",
"timeUnit":"Days",
"timeReq":"8.33",
"positionX":493,
"positionY":101,
"lockStatus":"unlocked"
}
],
"milestones":[
{
"id":"task_1",
"milestoneName":"Start",
"positionX":149,
"positionY":109,
"lockStatus":"unlocked",
"milestoneDate":"2015-04-07"
},
{
"id":"task_2",
"milestoneName":"Finish",
"positionX":989,
"positionY":367,
"lockStatus":"unlocked",
"milestoneDate":"2015-04-22"
}
],
"connections":[
{
"connectionId":"con_10",
"pageSourceId":"task_1",
"pageTargetId":"task_3"
},
{
"connectionId":"con_20",
"pageSourceId":"task_3",
"pageTargetId":"task_2"
}
]
};
var dates = []
, ids = []
, filtered = $.map(data.milestones, function(value, index) {
dates.push(new Date(value.milestoneDate).getTime());
ids.push(value.id);
if (dates.length === data.milestones.length) {
var id = ids[$.inArray(Math.min.apply(Math, dates), dates)]
, res = $.grep(data.connections, function(task, key) {
return task.pageSourceId === id
})[0].pageTargetId;
return res
}
})[0];
document.write(filtered);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
I am looking to write a function which can look up a value based on a key and replace that value with another. The key is a tree from the start node of JSON. Here is the example.
var myData = {
name : 'Dan',
address: {
city : 'Santa Clara',
details : {
'prevhouse' : ''
}
}
}
Input to the function is a key tree. For eg, myData-address-details-prevhouse
When I pass this key with a new value, say 'Texas', the prevhouse value will get changed to the new value I am sending.
and new JSON will be
var myData = {
name : 'Dan',
address: {
city : 'Santa Clara',
details : {
'prevhouse' : 'Texas'
}
}
}
Here is what I wrote so far
var tree = key.split("-");
now the tree variable contains ["myData","address", "details","prevhouse"]
I know that we can access the object using myData[tree[0]][tree[1]][tree[2]], but somehow not able to get it dynamic from parsed value.
how do we generate this dynamically since the length of the depth is not known till runtime.
Hope to get a help.
try with this code:
var myData = {
name: 'Dan',
address: {
city: 'Santa Clara',
details: {
prevhouse: ''
}
}
};
function setAttribute(obj, key, value) {
var i = 1,
attrs = key.split('-'),
max = attrs.length - 1;
for (; i < max; i++) {
attr = attrs[i];
obj = obj[attr];
}
obj[attrs[max]] = value;
console.log('myData=', myData);
}
setAttribute(myData, "myData-address-details-prevhouse", "Texas");
here a working jsfiddle demo; see the console for the result
You should be able to iterate through each key because your JSON is just a JS object. So go through each key, check if it's defined, if it is, use that object for your next check. That'll get you where you want to go. Keep in mind you'll be setting the last key to your value.
basic psuedo-code without dealing with setting:
obj = data;
for (key in keys) {
obj = obj[key]
}
Something like this would do:
function update(node, path, value) {
path = path.split('-');
do {
node = node[path.splice(0, 1)];
} while(path.length > 1);
node[path[0]] = value;
}
Given that myData is the object, I think you should be using myData[tree[1]][tree[2]][tree[3]] and throwing away the first item in the array.
Something like this should work recursively (untested)
function updateValue(obj, key, value)
{
var keys = key.split('-');
updateObjectValue(obj, keys.shift(), value);
}
function updateObjectValue(obj, keyArray, value)
{
if (keyArray.length == 1) {
obj[keyArray[0]] = value;
}
else if (keyArray.length > 1) {
updateObject(obj[keyArray[0]], keyArray.shift(), value);
}
}