JSON data group by - javascript

I have json data which contain the whole database record now i need to perform group by on this return json data with sorting on particular category.
I think sorting is easy to do on json data but i am not sure how i can go with group by. I need to group by on particular set of data.
Any help/suggestion would be great help.
Thanks
ravi

var obj = [{ "session":"1","page":"a"},
{ "session":"1","page":"b"},
{ "session":"1","page":"c"},
{ "session":"2","page":"d"},
{ "session":"2","page":"f"},
{ "session":"3","page":"a"}];
function GroupBy(myjson,attr){
var sum ={};
myjson.forEach( function(obj){
if ( typeof sum[obj[attr]] == 'undefined') {
sum[obj[attr]] = 1;
}
else {
sum[obj[attr]]++;
}
});
return sum;
}
var result = GroupBy(obj,"page");
console.log("GroupBy:"+ JSON.stringify(result));
/// GroupBy(obj,"session") --> GroupBy:{"1":3,"2":2,"3":1}
/// GroupBy(obj,"page") --> GroupBy:{"a":2,"b":1,"c":1,"d":1,"f":1}

Check the http://linqjs.codeplex.com or http://jslinq.codeplex.com. It's javascript libraries that mimics LINQ. Here is other questions like yours:Javascript Dynamic Grouping

var obj = [{Poz:'F1',Cap:10},{Poz:'F1',Cap:5},{Poz:'F1',Cap:5},{Poz:'F2',Cap:20},{Poz:'F1',Cap:5},{Poz:'F1',Cap:15},{Poz:'F2',Cap:5},{Poz:'F3',Cap:5},{Poz:'F4',Cap:5},{Poz:'F1',Cap:5}];
Array.prototype.sumUnic = function(name, sumName){
var returnArr = [];
var obj = this;
for(var x = 0; x<obj.length; x++){
if((function(source){
if(returnArr.length == 0){
return true;
}else{
var isThere = [];
for(var y = 0; y<returnArr.length; y++){
if(returnArr[y][name] == source[name]){
returnArr[y][sumName] = parseInt(returnArr[y][sumName]) + parseInt(source[sumName]);
return false;
}else{
isThere.push(source);
}
}
if(isThere.length>0)returnArr.push(source);
return false;
}
})(obj[x])){
returnArr.push(obj[x]);
}
}
return returnArr;
}
obj.sumUnic('Poz','Cap');
// return "[{"Poz":"F1","Cap":45},{"Poz":"F2","Cap":25},{"Poz":"F3","Cap":5},{"Poz":"F4","Cap":5}]"

Related

multiple search pattern from string

I have this code below to search for a string of search string_search_* matched.
I'm wondering if there's any easier way to do this like maybe add multiple search term in indexof? is that possible?
My goal: just add variable string:
string_search4, 5, 6 and so on..
string = "this is a .bigcommerce.com site";
var string_search1 = 'cdn.shopify.com/s';
var string_search2 = '.bigcommerce.com/';
var string_search3 = 'woocommerce/';
// start checkig with SHOPIFY first
var s = string.indexOf(string_search1 );
var found_s = String(s);
// IF FOUND - look for the full url hubspot - like the mp4 url
if (found_s != '-1') {
var result = 'SHOPIFY'
return result;
}
// if NOT FOUND, check with BIGCOMMERCE
else {
var b = html.indexOf(string_search2);
var found_b = String(b);
if (found_b != '-1') {
var result = 'BIGCOMMERCE'
return result;
}
else {
var w = html.indexOf(string_search3);
var found_w = String(w);
if (found_w != '-1') {
var result = 'WOO COMMERCE'
return result;
}
else {
var result = 'CANNOT INDENTIFY CMS'
return result
}
}
}
This may look a little long, but is very expandable.
// Our "key" object and defaults
var sObj = function(id){
this.id = id;
this.found = false;
};
// Our self-contained object with search and result
// functions. This is were and how we can expand quickly
var s = {
'ob': [],
'find': function(haystack) {
if (this.ob) {
for(var x in this.ob) {
this.ob[x].found = (haystack.indexOf(this.ob[x].id) > -1);
}
}
},
'result': function() {
var r = "";
if (this.ob) {
for(var x in this.ob) {
if (this.ob[x].found) {
r += ","+this.ob[x].id;
}
}
}
return (r == "") ? r : r.substr(1);
}
};
// Create the object array with the "id"
// Add as many as you want.
s.ob.push(new sObj('shopify.com'));
s.ob.push(new sObj('bigcommerce.com'));
s.ob.push(new sObj('woocommerce.com'));
// quick debug for testing
//for(var x in s.ob) {
// console.log('x:['+ x +']['+ s.ob[x].id +']['+ s.ob[x].found +']');
//}
// Our string to be tested
var data = "this is a .bigcommerce.com site";
// check if the data matches one of the sObj ids
s.find(data);
// get the results
console.log('result:['+ s.result() +']');
// And for a second test (2 results)
data = "can you shopify.com or woocommerce.com me?";
s.find(data);
console.log('result:['+ s.result() +']');

get specific text from value with javascript

I have a json.json file like this
{
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
And this script im using to read the file
<script type='text/javascript'>
$(window).load(function(){
$.getJSON("json.json", function(person){
document.write(person.name3);
});
});
</script>
This script is made to point out all of the data from "name3" but i need only "dr3" value from "name3" to be stored to be written.
How to do that?
You can store it like this using combination of split() calls.
var dr3val = person.name3.split("&")[2].split("=")[1];
console.log(dr3val); // "Sting3"
The above will work if the order is same. Else you can use the below
var dr3val = person.name3.replace(/.*?dr3=(.+)?&.*/,"$1");
console.log(dr3val); // "Sting3"
You should change your json to this:
{
"name1":
{
"ts1" : "Hallo",
"ts2" : "Hillarry",
"ts3" : "Sting",
"ts4" : "Storm"
}
}
this way it makes your jsonstring much easier to use.
Get the data from it like this:
person.name1.ts1
var json = {
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
};
var name3 = json.name3.split('&');
for (var i = 0; i < name3.length; i++) {
if (name3[i].indexOf("dr3=") > -1) {
var value = name3[i].replace("dr3=", "");
alert(value);
}
}
Implement this jQuery plugin i made for a similar case i had to solve some time ago. This plugin has the benefit that it handles multiple occurring variables and gathers them within an array, simulating a webserver behaviour.
<script type='text/javascript'>
(function($) {
$.StringParams = function(string) {
if (string == "") return {};
var result = {},
matches = string.split('&');
for(var i = 0, pair, key, value; i < matches.length; i++) {
pair = matches[i].split('=');
key = pair[0];
if(pair.length == 2) {
value = decodeURIComponent(pair[1].replace(/\+/g, " "));
} else {
value = null;
}
switch($.type(result[key])) {
case 'undefined':
result[key] = value;
break;
case 'array':
result[key].push(value);
break;
default:
result[key] = [result[key], value];
}
}
return result;
}
})(jQuery);
</script>
Then in your code do:
<script type='text/javascript'>
$(window).load(function(){
var attributes3;
$.getJSON("json.json", function(person){
attributes3 = $.StringParams(person.name3)
console.log(attributes3.dr3);
});
});
</script>
Underscore solution:
_.map(json, function(query) { //map the value of each property in json object
return _.object( //to an object created from array
query.split('&') //resulting from splitting the query at &
.map(function(keyval) { //and turning each of the key=value parts
return keyval.split('='); //into a 2-element array split at the equals.
);
})
The result of the query.split... part is
[ [ 'ts1', 'Hallo'], ['ts2', 'Hillarry'], ... ]
Underscore's _.object function turns that into
{ ts1: 'Hallo', ts2: 'Hillarry', ... }
The end result is
{
name1: { ts1: 'hHallo', ts2: 'Hillarry, ...},
name2: { ...
}
Now result can be obtained with object.name3.dr3.
Avoiding Underscore
However, if you hate Underscore or don't want to use it, what it's doing with _.map and _.object is not hard to replicate, and could be a useful learning exercise. Both use the useful Array#reduce function.
function object_map(object, fn) {
return Object.keys(object).reduce(function(result, key) {
result[key] = fn(object[key]);
return result;
}, {});
}
function object_from_keyvals(keyvals) {
return keyvals.reduce(function(result, v) {
result[v[0]] = v[1];
return result;
}, {});
}
:
var person={
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
var pN = person.name3;
var toSearch = 'dr3';
var ar = pN.split('&');
var result = '';
for(var i=0; i< ar.length; i++)
if(ar[i].indexOf(toSearch) >= 0 )
result=ar[i].split('=')[1];
console.log('result=='+result);

Trouble iterating through an object

I have an object that looks like this:
salesDetails:{ "1":{
"date":"06/22/2014",
"amount":"45",
"currency":"CAD",
"productID":"23",
"status":1},
"2":{
"date":"06/22/2014",
"amount":"120",
"currency":"USD",
"productID":"23",
"status":1},
"3":{
"date":"06/23/2014",
"amount":"100",
"currency":"USD",
"productID":"21",
"status":2},
"4":{
"date":"06/23/2014",
"amount":"250",
"currency":"CAD",
"productID":"25",
"status":1},
"5":{
"date":"06/23/2014",
"amount":"180",
"currency":"USD",
"productID":"24",
"status":1}
}
What i am trying to do is to get all the amount per currency of all that has status of "1" and put it in an object that should look like this:
perCurrency: {
"CAD":{
"0":"45",
"1":"250"},
"USD":{
"0":"120",
"1":"180"}
}
I was able to put all the currency in an object but I'm having trouble with the amount, the last amount from the object overlaps the previous one. I keep on getting {"CAD":{"1":"250"},"USD":{"1":"180"}} Here's my code so far.
function countPerCurrency(){
var currencyArray = new Array();
var perCurrency = {};
var totalSales = Object.size(salesDetails);
for(var i=1; i <= totalSales; i++){
var currency = salesDetails[i]["currency"];
var amount = salesDetails[i]["amount"];
var status = salesDetails[i]["status"];
var totalCurrency = Object.size(currencyAmount[currency]);
var currencyCtr = {};
if(status == 1){
if(!inArray(currency, currencyArray)){
currencyArray.push(currency);
currencyCtr[totalCurrency] = amount;
perCurrency[currency] = currencyCtr;
} else {
var currencyAdd = {};
currencyAdd[totalCurrency] = amount;
perCurrency[currency] = currencyAdd;
}
}
}
}
I know it might seem easy, but I'm lost here.. TIA! :)
The previously accepted answer uses an array of values, whereas you asked for an object. Here's an object version:
var perCurrency = {};
var currencyCount = {};
Object.keys(salesDetails).forEach(function(key) {
var obj = salesDetails[key];
var currency;
if (obj.status == 1) {
currency = obj.currency;
// If this is first for this currency, add it to objects
if (!currencyCount[currency]) {
currencyCount[currency] = 0;
perCurrency[currency] = {};
}
// Add currency values
perCurrency[currency][currencyCount[currency]++] = obj.amount;
}
});
BTW, this has nothing to do with jQuery.
Note that Object.keys is ES5 so may need a polyfill for older browsers, see MDN:Object.keys for code.
try something like this
function countPerCurrency(){
var perCurrency = {};
var totalSales = Object.size(salesDetails);
for(var i=1; i <= totalSales; i++){
var currency = salesDetails[i]["currency"];
var amount = salesDetails[i]["amount"];
var status = salesDetails[i]["status"];
if(status == '1'){
if(perCurrency.hasOwnProperty(currency)){
// if currency already present than get currency array.
var currency_arr = perCurrency[currency];
// add new value to existing currency array.
currency_arr.push(amount);
}else{
// if currency not present than create currency array and add first value;
var currency_arr = [];
currency_arr.push(amount);
// add newly created currency array to perCurrency object
perCurrency[currency] = currency_arr;
}
}
}
console.log(perCurrency);
}
output
perCurrency: {
"CAD":["45","250"],
"USD":["120","180"],
}
I have created currency array instead of key value pair
Change your code like this, i have simplified your things,
function countPerCurrency() {
var perCurrency = {};
var currencyArray = [];
for(i in salesDetails)
{
if(!perCurrency.hasOwnProperty(salesDetails[i].currency) && salesDetails[i].status === "1")
perCurrency[salesDetails[i].currency] = [];
if(salesDetails[i].status === "1")
{
currencyArray = perCurrency[salesDetails[i].currency];
currencyArray.push(salesDetails[i].amount);
perCurrency[salesDetails[i].currency] = currencyArray;
}
}
}
sorry for the late conversation anyway try like this use .each()
var CAD = new Array();
var USD = new Array();
$.each(salesDetails, function (i, value) {
if (value.status == 1) {
if (value.currency == "CAD") {
CAD.push(value.amount);
} else if (value.currency == "USD") {
USD.push(value.amount);
}
}
});
var perCurrency = {
"CAD": CAD,
"USD": USD
}
Demo

filter objects matching details

Functions works fine, they filter inventory by barcode, and manufacturer. I want to make it like default angularjs filtering. If I choose manufacturer - LG and barcode - 112 and if they don't match, then it shouldn't display anything.
But for now it displays separately, when i click on filter function it filters barcode when on filter2 function filter manufacturer
$scope.filter = function(barcode) {
var filtered = [];
for(var i = 0; i < $scope.inventories.length; i++){
if($scope.inventories[i].barcode == barcode){
filtered.push($scope.inventories[i]);
}
}
$scope.filtered_inventories = filtered;
};
$scope.filter2 = function(manufacturer) {
var filtered = [];
for(var i = 0; i < $scope.inventories.length; i++){
if($scope.inventories[i].manufacturer == manufacturer){
filtered.push($scope.inventories[i]);
}
}
$scope.filtered_inventories = filtered;
};
Try this
$scope.filter = function (barcode, manufacturer) {
var filtered = [];
for(var i = 0; i < $scope.inventories.length; i++){
if($scope.inventories[i].barcode == barcode || $scope.inventories[i].manufacturer == manufacturer){
filtered.push($scope.inventories[i]);
}
}
$scope.filtered_inventories = filtered;
};
You could create a more general way of filtering:
$scope.filterByBarcode = function(list, key, value) {
return list.filter(function(item){
return item[key] === value;
});
};
And when you filter you could call:
$scope.filtered_inventories = $scope.filter($scope.filter($scope.inventories, 'barcode', 112), 'manufacturer', 'LG')
But to simplify that you could create a function:
$scope.filterByBarcodeAndManufacturer = function(barcode, manufacturer) {
$scope.filtered_inventories =
$scope.filter($scope.filter($scope.inventories, 'barcode', barcode), 'manufacturer', manufacturer);
}

Dynamically building array, appending values

i have a bunch of options in this select, each with values like:
context|cow
context|test
thing|1
thing|5
thing|27
context|beans
while looping through the options, I want to build an array that checks to see if keys exist, and if they don't they make the key then append the value. then the next loop through, if the key exists, add the next value, comma separated.
the ideal output would be:
arr['context'] = 'cow,test,beans';
arr['thing'] = '1,5,27';
here's what i have so far, but this isn't a good strategy to build the values..
function sift(select) {
vals = [];
$.each(select.options, function() {
var valArr = this.value.split('|');
var key = valArr[0];
var val = valArr[1];
if (typeof vals[key] === 'undefined') {
vals[key] = [];
}
vals[key].push(val);
});
console.log(vals);
}
Existing code works by changing
vals=[];
To
vals={};
http://jsfiddle.net/BrxuM/
function sift(select) {
var vals = {};//notice I made an object, not an array, this is to create an associative array
$.each(select.options, function() {
var valArr = this.value.split('|');
if (typeof vals[valArr[0]] === 'undefined') {
vals[valArr[0]] = '';
} else {
vals[valArr[0]] += ',';
}
vals[valArr[0]] += valArr[1];
});
}
Here is a demo: http://jsfiddle.net/jasper/xtfm2/1/
How about an extensible, reusable, encapsulated solution:
function MyOptions()
{
var _optionNames = [];
var _optionValues = [];
function _add(name, value)
{
var nameIndex = _optionNames.indexOf(name);
if (nameIndex < 0)
{
_optionNames.push(name);
var newValues = [];
newValues.push(value);
_optionValues.push(newValues);
}
else
{
var values = _optionValues[nameIndex];
values.push(value);
_optionValues[nameIndex] = values;
}
};
function _values(name)
{
var nameIndex = _optionNames.indexOf(name);
if (nameIndex < 0)
{
return [];
}
else
{
return _optionValues[nameIndex];
}
};
var public =
{
add: _add,
values: _values
};
return public;
}
usage:
var myOptions = MyOptions();
myOptions.add("context", "cow");
myOptions.add("context","test");
myOptions.add("thing","1");
myOptions.add("thing","5");
myOptions.add("thing","27");
myOptions.add("context","beans");
console.log(myOptions.values("context").join(","));
console.log(myOptions.values("thing").join(","));
working example: http://jsfiddle.net/Zjamy/
I guess this works, but if someone could optimize it, I'd love to see.
function updateSiftUrl(select) { var
vals = {};
$.each(select.options, function() {
var valArr = this.value.split('|');
var key = valArr[0];
var val = valArr[1];
if (typeof vals[key] === 'undefined') {
vals[key] = val;
return;
}
vals[key] = vals[key] +','+ val;
});
console.log(vals);
}
Would something like this work for you?
$("select#yourselect").change(function(){
var optionArray =
$(":selected", $(this)).map(function(){
return $(this).val();
}).get().join(", ");
});
If you've selected 3 options, optionArray should contain something like option1, option2, option3.
Well, you don't want vals[key] to be an array - you want it to be a string. so try doing
if (typeof vals[key] === 'undefined') {
vals[key] = ';
}
vals[key] = vals[key] + ',' + val;

Categories

Resources