Wednesday, November 11, 2015

jQuery array to CSV string - Two methods

The code below can be used to convert an name value type array in JavaScript to a CSV string, which could then be copied to the clipboard or returned as  .CSV file.

The first is for a JS array object with multiple arrays inside:

 function convertToCSV(objArray) {  
   var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;  
   var str = '';  
   for (var i = 0; i < array.length; i++) {  
     var line = '';  
     for (var index in array[i]) {  
       if (line !== '') line += ',';  
       line += array[i][index];  
     }  
     str += line + '\r\n';  
   }  
   return str;  
 }  
 function functionOne() {  
   var arrReturn = [];  
   var arrKeys = [];  
   var arrValues = [];  
   $.each(rowData, function (idx2, val2) {  
     var strKey = idx2;  
     var strValue = val2;  
     arrKeys.push(strKey);  
     arrValues.push(strValue);  
   });  
   arrReturn.push(arrKeys);  
   arrReturn.push(arrValues);  
   var result = convertToCSV(arrReturn);    
 }  

The second, simpler and faster version only supports one name value type array. e.g. var arr = ["Name":"Value];

 function functionTwo() {  
   var arrKeys = [];  
   var arrValues = [];  
   $.each(rowData, function (idx2, val2) {  
     var strKey = idx2;  
     var strValue = val2;  
     arrKeys.push(strKey);  
     arrValues.push(strValue);  
   });  
   var strKeys = arrKeys.join(",") + '\r\n';  
   var strValues = arrValues.join(",");  
   var result = strKeys.concat(strValues);   
 }  

JSFiddle - example with performance comparison to another method.

Wednesday, November 4, 2015

jqGrid Date Picker for column filtering

Using jqGrid 4.9.2, you can add a date picker to a column filter using the following code:

 grid.setFilterDate = function(table, column) {  
     $('#' + table).jqGrid('setColProp', column, {  
       searchoptions: {  
         dataInit: _loadDatePicker  
       },  
       dataEvents: [{  
         type: 'change',  
         fn: function (e) {  
           console.log("change via datePicker failed - search dialog detected");  
           //table.toggleToolbar();  
         }  
       }]  
     });      
   }  

 function _loadDatePicker (filters) {  
     setTimeout(function() {  
       $(filters).datepicker({  
         dateFormat: 'mm/dd/yy',  
         autoSize: true,  
         changeYear: true,  
         changeMonth: true,  
         showButtonPanel: true,  
         showWeek: true,  
         onSelect: function() {  
           var $grid, grid;  
           if (typeof (this.id) === "string" && this.id.substr(0, 3) === "gs_") {  
             // in case of searching toolbar  
             $grid = $(this).closest('div.ui-jqgrid-hdiv')  
               .next('div.ui-jqgrid-bdiv')  
               .find("table.ui-jqgrid-btable:first");  
             if ($grid.length > 0) {  
               grid = $grid[0];  
               if ($.isFunction(grid.triggerToolbar)) {  
                 setTimeout(function() {  
                   grid.triggerToolbar();  
                 }, 50);  
               }  
             }  
           } else {  
             // refresh the filter in case of  
             // searching dialog   
             $(this).trigger('change');  
           }  
         }  
       });  
     }, 100);  
   };  

To filter when a date is selected, use the onSelect option:

      onSelect: function() {   
       var $grid, grid;   
       if (typeof (this.id) === "string" && this.id.substr(0, 3) === "gs_") {   
        // in case of searching toolbar   
        $grid = $(this).closest('div.ui-jqgrid-hdiv')   
         .next('div.ui-jqgrid-bdiv')   
         .find("table.ui-jqgrid-btable:first");   
        if ($grid.length > 0) {   
         grid = $grid[0];   
         if ($.isFunction(grid.triggerToolbar)) {   
          setTimeout(function() {   
           grid.triggerToolbar();   
          }, 50);   
         }   
        }   
       } else {   
        // refresh the filter in case of   
        // searching dialog    
        $(this).trigger('change');   
       }   
      }   

The key to filtering onSelect is grid.TriggerToolbar(). Because setFilterDate is refactored, you either need to pass in the grid "table" ID or search for it inside the function.

Source

Monday, November 2, 2015

IP Address Validation RegEx

IP Address Validation RegEx via Javascript on HackerRank:

 function processData(input) {  
   var lines = input.split("\n");  
     n  = parseInt(lines[0]);  
     ip4 = /\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b/;  
     ip6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/;  
   for (var i = 1; i < n + 1; i++) {  
     if (ip4.test(lines[i])) {  
       console.log("IPv4");  
     } else if (ip6.test(lines[i])) {  
       console.log("IPv6");  
     } else {  
       console.log("Neither");  
     }  
   }    
 }   
 process.stdin.resume();  
 process.stdin.setEncoding("ascii");  
 _input = "";  
 process.stdin.on("data", function (input) {  
   _input += input;  
 });  
 process.stdin.on("end", function () {  
   processData(_input);  
 });  

Test results:
Test Case #0:   0.09s
Test Case #1:   0.09s
Test Case #2:   0.09s
Test Case #3:   0.09s

Sunday, November 1, 2015

Split Phone Numbers RegEx

Split Phone Numbers via Regex and Javascript on HackerRank:

 function processData(input) {  
   var lines = input.split("\n");  
     regex = /^(\d{1,3})[-?\s]?(\d{1,3})[-?\s]?(\d{4,10})/;  
   for (var i = 1; i < lines.length; i++) {  
     var str = lines[i].split(regex).filter(Boolean);  
     console.log("CountryCode=" + str[0] + ",LocalAreaCode=" + str[1] + ",Number=" + str[2]);  
   }  
 }   
 process.stdin.resume();  
 process.stdin.setEncoding("ascii");  
 _input = "";  
 process.stdin.on("data", function (input) {  
   _input += input;  
 });  
 process.stdin.on("end", function () {  
   processData(_input);  
 });  

Test results:
Test Case #0: 0.1s
Test Case #1: 0.09s
Test Case #2: 0.1s
Test Case #3: 0.09s
Test Case #4: 0.1s
Test Case #5: 0.1s
Test Case #6: 0.09s
Test Case #7: 0.09s
Test Case #8: 0.09s
Test Case #9: 0.09s
Test Case #10: 0.09s

Diagonal Difference (JavaScript)

HackerRank problem Diagonal Difference using JavaScript:


 function processData(input) {  
   var lines = input.split("\n");  
   var arr = [];  
   for (var i = 1; i < lines.length; i++) {  
     arr.push(lines[i].split(" "));  
   }  
   var sumTopLeft = 0;  
   var sumBotLeft = 0;  
   for (var j = 0; j < arr.length; j++) {  
     sumTopLeft += parseInt(arr[j][j]);  
   }  
   var count = -1;  
   for (var k = arr.length - 1; k >= 0; k--) {  
     count++;  
     sumBotLeft += parseInt(arr[k][count]);  
   }  
   var diff = Math.abs(sumTopLeft - sumBotLeft);  
   console.log(diff);  
 }   
 process.stdin.resume();  
 process.stdin.setEncoding("ascii");  
 _input = "";  
 process.stdin.on("data", function (input) {  
   _input += input;  
 });  
 process.stdin.on("end", function () {  
   processData(_input);
 });  

Test results:
Test Case #0:   0.09s
Test Case #1:   0.09s
Test Case #2:   0.1s
Test Case #3:   0.1s
Test Case #4:   0.09s
Test Case #5:   0.09s
Test Case #6:   0.09s
Test Case #7:   0.09s
Test Case #8:   0.09s
Test Case #9:   0.1s
Test Case #10:   0.09s

Thursday, October 29, 2015

Simple Array Sum Javascript

HackerRank.com Simple Array Sum Javascript



 var sum = 0;  
 function processData(input) {  
   var lines = input.split("\n");  
   var n = parseInt(lines[0]);  
   var arr = lines[1].split(" ");  
   for (var i = 0; i < input.length; i++) {  
     sum += parseInt(arr[i]);  
   }  
   console.log(sum);  
 }   
   
 process.stdin.resume();  
 process.stdin.setEncoding("ascii");  
 _input = "";  
 process.stdin.on("data", function (input) {  
   _input += input;  
 });  
   
 process.stdin.on("end", function () {  
   processData(_input);  
 });  
   

Tuesday, October 27, 2015

Two Sum via C#

Problem: Given an array of integers, find two numbers such that they add up to a specific target number.

Answer via C# using HashTable:

 public class Solution {  
   public int[] TwoSum(int[] nums, int target) {  
     List<int> arr = new List<int>();  
     Hashtable hashTable = new Hashtable();  
     for (int i = 0; i < nums.Length;i++)  
     {  
       hashTable[nums[i]] = i;  
     }  
       
     for (int i = 0; i < nums.Length; i++)  
     {  
       // get key2, index2  
       var key2 = target - nums[i];  
       if (hashTable.Contains(key2) && ((Int32)hashTable[key2] != i) && ((Int32)hashTable[key2] > i))  
       {  
         int i2 = (Int32)hashTable[key2];  
         arr.Add(i + 1);  
         arr.Add(i2 + 1);  
       }  
     }  
       
     return arr.ToArray();  
   }  
 }  

Rotate Array via Javascript

Leetcode rotate array via Javascript using reversal:

 /**  
  * @param {number[]} nums  
  * @param {number} k  
  * @return {void} Do not return anything, modify nums in-place instead.  
  */  
 var rotate = function(nums, k) {  
   if(nums.length === 0) {  
    throw "provide valid array";  
   }  
      k = k % nums.length;  
    
   //length of first part  
   var a = nums.length - k;   
    
   reverse(nums, 0, a-1);  
   reverse(nums, a, nums.length-1);  
   reverse(nums, 0, nums.length-1);  
 };  
   
 function reverse(arr, left, right){  
   while(left < right){  
     var temp = arr[left];  
     arr[left] = arr[right];  
     arr[right] = temp;  
     left++;  
     right--;  
   }    
 }  

Monday, December 15, 2014

Entity Framework Code-First Migrations: Seed data using AddOrUpdate

Bottom line

By adding sample data to the Configuration.cs file in your Migrations folder, model updates can be easily administered to your database while avoiding unnecessary and time consuming errors.

The issue

If you're using migrations for your database updates, you may run into migration errors as a result of duplicate data and incorrect foreign key relationships. Utilizing the AddOrUpdate function correctly will avoid migration errors such as:
  • Sequence contains more than one element
  • The INSERT statement conflicted with the FOREIGN KEY constraint 

The code

After enabling Code-First Migrations in your project, you should see the folder Migrations with Configration.cs located inside. Configuration.cs and in the Seed method, I've added the following in order to create four records inside my Permission table:

var permissions = new List<Permission>
            {
                new Permission {Name = "Create Item", Description = "Grants user the ability to create items"},
                new Permission {Name = "Modify Item", Description = "Grants user the ability to modify items"},
                new Permission {Name = "Delete Item", Description = "Grants user the ability to delete items"},
                new Permission {Name = "Read Item", Description = "Grants user the ability to read items"},
            };
 permissions.ForEach(p => context.Permissions.AddOrUpdate(n => n.Name, p));
 context.SaveChanges();

While there are several ways to add data to your context, using List<> will surely be one of the quickest ways.

What you may have missed

Many sample solutions, Stack Overflow answers and guides fail to use the full capability of AddOrUpdate by simply not adding a identifying property to the identification expression (see bold):

itemList.ForEach(item => context.ItemDbSet.AddOrUpdate(n => n.Name, item));

In this example, the Name property on our Permission entity is used as the identification property for comparing the seed data to what already exists in the database. If an item with the same name exists, it will update the item as opposed to adding a new one. This will save your existing relationships between records and avoid most issues with migrating model updates with existing data.

The context

This is for a ASP.NET SPA running Entity Framework 6, Visual Studio 2013, Code-First, Migrations enabled, SQL Server (or LocalDb) and Web API.

Helpful links

Code First Migrations and Deployment with the Entity Framework in an ASP.NET MVC Application