Javascript array not getting modified - javascript

I have some JSON data in the "data" variable.
FORMAT :
{
"0" : {"names":"Pooja, Trivedi"},
"1" : {"names":"Pooja, Rooster"}
}
I need to implement a map so as to count the different names:
Pooja = 2
Trivedi = 1
Rooster = 1
Here is the implementation:
map = new Array();
data = jQuery.parseJSON(data); //convert JSON to object
for (var i = 0; i < data.length; i++) {
var names = data[i].names.split(','); //split the CSVs
for (var j = 0; j < names.length; j++) {
if (map[names[j].trim()] === undefined) {
map[names[j].trim()] = 1;
} else {
map[names[j].trim()]++;
}
}
console.log(map); //shows progressively filled arrays
}
console.log(map); //shows [], an empty array
Inside the loop, the map is updated.
However after the end of the i loop, all we have is an empty array.
How is this to be resolved?

First of all, you don't want to use for (var i = 0; i < data.length; i++) to traverse your data object, because a Javascript object doesn't have a length property like an array would. So, use a for (var i in data) instead, to traverse all the keys in the object.
This works:
var data = {
"0" : {"names":"Pooja, Trivedi"},
"1" : {"names":"Pooja, Rooster"}
}
var map = {};
for (var i in data) {
var names = data[i].names.split(',');
for (var j in names) {
var name = names[j].trim();
if (map[name]) {
map[name]++;
} else {
map[name] = 1;
}
}
console.log(map); //shows progressively filled arrays
}
console.log(map); //shows the full array
And you don't want to use an array as your map. You should instead use an object.

I like this version better:
var data = {
"0" : {"names":"Pooja, Trivedi"},
"1" : {"names":"Pooja, Rooster"}
};
var nameCounts = {};
for (var item in data) {
data[item].names.split(", ").forEach(function (name) {
if (name in nameCounts) {
nameCounts[name]++;
} else {
nameCounts[name] = 1;
}
});
}
console.log(nameCounts);

Related

Javascript Looping through objects

var a = {
element:'input',
parent:'div1',
name:'inp',
type:'text',
value:'aa'
}
I want to loop through this object starting from name attribute using for in loop
But I am unable to do this using for in loop
is there any way to loop through the object starting from the name attribute
Old way:
for (var key in a) {
if (a.hasOwnProperty(key)) {
// todo something with a[key]
}
}
ES6 way:
Object.keys(a).forEach(function(key) {
// todo something with a[key]
});
for(var prop in a) {
console.log(a[prop]);
}
You could do something like this:
var keys = Object.keys(a);
var length = keys.length;
var startAt = keys.indexOf("name");
for(var i = 0; i < length ; i++) {
var prop = keys[(i+startAt)%length];
console.log(prop, a[prop]);
}
Or:
var keys = Object.keys(a).sort(function(a,b){ return a !== "name" });
for(var i = 0; i < keys.length; i++) {
var prop = keys[i];
console.log(prop, a[prop]);
}
Or:
var keys = Object.keys(a);
var idx = keys.indexOf("name");
if(idx > 0) {
var tmp = keys[0];
keys[0] = keys[idx];
keys[idx] = tmp;
}
for(var i = 0; i < keys.length; i++) {
var prop = keys[i];
console.log(prop, a[prop]);
}
But keep in mind that objects are unordered lists even though most browsers keep object properties in the order in which they were added.
I believe you can do it as follows:
function loopFromIndex(input, index) {
var started = false;
for (var property in input) {
started = started || (index === property);
if (started) {
//process iteration
}
}
}
You are still looping the whole property set, but when you encounter the given index, you will start the real loop.

Parsing an array of objects and pushing selectively to new object

I am trying to parse a JSON response from transloadit and save off the result objects in groups to store separately.
This is the JSON: https://jsonblob.com/552917cee4b0237a964c0de1
I am trying this...
var results = response.results;
var versions = {};
for (var index in results) {
var this_key = index;
for (var i = 0; i < results[index].length; i++) {
if(results[index][i].md5hash === media.md5){
versions[this_key] += results[index][i];
}
}
}
But when I console versions I am only getting
{":original":"undefined[object Object]"}
Whereas I would have expected something closer to what I want to achieve which is
{":original":[object Object],"l":[object Object]}
The intention is to insert this into MongoDB so that I am left with
"versions":{"l":{"name":"foo"...},"m":{"name":"bar"...}}
The issue you are facing is because of the versions[this_key] not initialized.
Check http://jsfiddle.net/Lhzgc7tq/
var results = response.results;
var versions = {};
for (var index in results) {
var this_key = index;
for (var i = 0; i < results[index].length; i++) {
if(results[index][i].md5hash === media.md5){
versions[this_key] = "";
versions[this_key] += results[index][i];
}
}
}
console.log(versions);

Copying array of objects into another array is it reference type in JQuery

I have a array of objects TransactionVModel.FiltersList[].
When I copy this array to another array fltrList[] and if I modify any of the object in array fltrList will it get reflect in Array TransactionVModel.FiltersList in JQuery ? For better clarity below is my example. As per me since it is a reference type it should update array TransactionVModel.FiltersList as well but in my scenario it is not happening, can I know why it is not happening ?
TransactionVModel.FiltersList is declared as ko.observableArray(); in my code.
function UpdateSelectedFilters(data) {
var fltrList = [];
fltrList = TransactionVModel.FiltersList();
for (var i = 0; i < data.length ; i++) {
var index = fltrList.indexOf(data[i]);
if (index != -1) {
var fltrObj = fltrList[index];
var fltrValArr = [];
fltrValArr = data.valueItems;
for (var j = 0; j < fltrValArr.length; j++) {
if (fltrValArr[j].IsSelected == true) {
if (fltrObj.indexOf(fltrValArr[j]) != -1) {
var selectedVal = fltrObj[fltrObj.indexOf(fltrValArr[j])];
selectedVal.IsSelected = true;
}
}
}
}
}
In my scenario I am updating selectedVal.IsSelected property but it is not reflecting the observableArray TransactionVModel.FiltersList.
You need to tell knockout that your array has changed with valueHasMutated:
function UpdateSelectedFilters(data) {
var fltrList = [];
fltrList = TransactionVModel.FiltersList();
//...
TransactionVModel.FiltersList.valueHasMutated();
}

Storing array object in a multidimentional array element in javascript

I have a scenario in which i've to store array object in a array.My Javascript code is
var myArray= new Array(5,5);
for(dataIndex in data.data){
for(myIndex in data.data[dataIndex].myObject){
var xrow =data.data[dataIndex].myObject[myIndex].row;
var xcolumn =data.data[dataIndex].myObject[myIndex].column;
myarray[xrow][xcolumn] = data.data[dataIndex].myObject[myIndex];
}
}
but could not store any data object in the array.Can anyone help me out sort this?
It looks like you're coming from PHP, where an array is both a sequence of elements and/or key-value pairs? An array in javascript is just a sequence. (Actually, that's not 100% true, but it is for all intents and purposes.) What you want is an object. An object is a series of key value pairs. The keys and values can be any object, from a string to an array to a function.
var myObj = {};
// or assigning properties up front
var myOtherObj = {'foo': 'bar', 'baz': 12 };
My problem was not declaring and setting value for the javascript array.I was able to acheive it by this.
var YourArrayHere = new Array();
YourArrayHere.length = [first dimension array length here];
for(var count = 0; count < YourArrayHere.length; count++)
{
var TempSecondArray = new Array();
TempSecondArray.length = [sec dimension array length here];
YourArrayHere[count] = TempSecondArray;
}
Ok got a working demo. Took me a while to figure it out. Was fun. It can be optmized.
EDIT: you don't really need a MAX.
jsfiddle: http://jsfiddle.net/Grimbode/7B8CK/1/
var data = {
"data":[
{"myObject":[
{"row":0, "column":0},
{"row":0, "column":1},
{"row":0, "column":2},
]
},
{
"myObject":[
{"row":1, "column":0},
{"row":1, "column":1},
{"row":1, "column":2}
]
}
]
};
var result = new Array();
for(var i = 0; i < data.data.length; i++)
{
var temp = new Array();
var row = (data.data[i].myObject.length > 0) ? data.data[i].myObject[0].row: null;
for(var j = 0; j < data.data[i].myObject.length; j++)
{
console.log('row: ' + data.data[i].myObject[j].row + ', column: ' + data.data[i].myObject[j].column);
temp[data.data[i].myObject[j].column] = [data.data[i].myObject[j]];
}
if(row != null){ result[row] = temp;}
console.log(result);
}
console.log('Final:');
console.log(result);
jsfiddle: http://jsfiddle.net/Grimbode/7B8CK/
I represented data as best as I could to fit your example
var MAX_X = 10;
var MAX_Y = 10;
var data = {
"data":[
{"myObject":[
{"row":0, "column":0},
{"row":0, "column":1},
{"row":0, "column":2},
]
},
{
"myObject":[
{"row":1, "column":0},
{"row":1, "column":1},
{"row":1, "column":2}
]
}
]
};
var result = new Array(MAX_X);
for(var i = 0; i < data.data.length; i++)
{
var temp = new Array(MAX_Y);
var row = (data.data[i].myObject.length > 0) ? data.data[i].myObject[0].row: null;
for(var j = 0; j < data.data[i].myObject.length; j++)
{
console.log('row: ' + data.data[i].myObject[j].row + ', column: ' + data.data[i].myObject[j].column);
temp[data.data[i].myObject[j].column] = [data.data[i].myObject[j]];
}
if(row != null){ result[row] = temp;}
console.log(result);
}
console.log('Final:');
console.log(result);

How do I merge a list of results into a compacted object with totals

I'm looping through a set of inputs. I need to tally up the grouped totals.
var compoundedArray = new Array();
holder.find(".dataset input").each(function(index) {
var val = $(this).val();
var dataType = $(this).data("type");
var localObj = {};
localObj[dataType] = val;
compoundedArray.push(localObj);
});
I have an object like this
[
{
"growth":30
},
{
"growth": 40
},
{
"other": 20
}
]
how do I loop through the object to produce something like
[
{
"growth": 70
},
{
"other": 20
}
]
if I looped over the initial array object
for (var i = 0; i < compoundedArray.length; i++) {
console.log(compoundedArray[i]);
}
how would I go about checking to ensure I don't have duplicates - and that I can tally up the results?
I think your selection of data structure is a bit too complicated. Try something like.
var compoundedObject = {};
holder.find(".dataset input").each(function(index) {
var val = $(this).val();
var dataType = $(this).data("type");
//Assuming all values are integers and can be summed:
if( compoundedObject.hasOwnProperty(dataType) )
{
compoundedObject[dataType] += val;
}
else
{
compoundedObject[dataType] = val;
}
});
You will end up with an object, not an array though.
var add=function (a,b){ a=a||0; b=b||0; return a+b};
var input=[ {growth:30},{growth:40},{other:20} ],output=[],temp={};
$.each(input,function(i,o){
var n;
for(i in o)
{n=i;break}
temp[n]=add(temp[n],o[n]);
});
$.each(temp,function(i,o){
var k={};
k[i]=o;
output.push(k)
});
find output at output variable.
Do not post much specific question, It might not help others.
This works. And it's pure javascript.
var totals = {};
for (var i = 0; i < compoundedArray.length; i++) {
var item = compoundedArray[i];
for (var key in item) {
totals[key] = (totals[key] || 0) + item[key]
}
};
You can loop trough an Object with a for loop.
If you want to delete an item simply set it to null.
Example:
for(var i in compoundedArray){
for(var j in compoundedArray){
if(i == j){
compoundedArray[i] += compoundedArray[j];
compoundedArray[j] = null;
}
}
}
You can do the following:
var totals = [], tmp = {};
for (var i = 0; i < compoundedArray.length; i++) {
var obj = compoundedArray[i];
for (var j in obj) {
tmp[j] = tmp[j] || 0;
tmp[j] += obj[j];
}
}
for(var k in tmp) {
var obj = {};
obj[k] = tmp[k];
totals.push(obj);
}
See this working demo

Categories

Resources