I'm trying to create an array of hashes in javascript. For instance;
[{id: "1", demo: 1, demo2: 2, demo3: 3}, {id: "2", demo: 1, demo2: 2, demo3: 3}, {id: "3", demo: 1, demo2: 2, demo3: 3}..]
I have loop through from 2 for loops but because the hash variable name is the same during the loop it writes on the previous one, not pushing it to array;
var rows = [];
var exc_hash = {};
for (k = 0; k < 2; k++) {
for (m = 1; m < 4; m++) {
var exc = ((data[m][k][1][2] == 'OK') ? data[m][k][1][0] : data[m][k][1][2]);
exc_hash["id"] = data[0][k];
exc_hash[(data[m][k][7])] = exc;
}
rows.push(exc_hash);
}
console.log(rows);
When I console log the rows, it prints;
[{id: "1", demo: 1, demo2: 2, demo3: 3}, {id: "1", demo: 1, demo2: 2, demo3: 3}]
The last hash written as for the first hash as well.
EDIT:
Thank you but when I use this like you show;
var rows = [];
for (k = 0; k < 2; k++) {
for (m = 1; m < 4; m++) {
var exc_hash = {
id: k
};
exc_hash['data'+m] = 'data'+m+k;
rows.push(exc_hash);
}
}
console.log(rows);
it prints;
0:{id: 0, data1: "data10"}
1:{id: 0, data2: "data20"}
2:{id: 0, data3: "data30"}
3:{id: 1, data1: "data11"}
4:{id: 1, data2: "data21"}
5:{id: 1, data3: "data31"}
However, I would like to get this;
0:{id: 0, data1: "data10", data2: "data20", data3: "data30"}
1:{id: 1, data1: "data11", data2: "data21", data3: "data31"}
How can I accomplish this?
This is a fairly classic problem. You're recycling the same object through each iteration of the loop so you're inserting the exact same object into the array.
To fix this, declare that internally:
var rows = [];
for (k = 0; k < 2; k++) {
for (m = 1; m < 4; m++) {
var exc_hash = {
id: data[0][k]
};
exc_hash[(data[m][k][7])] = ((data[m][k][1][2] == 'OK') ? data[m][k][1][0] : data[m][k][1][2]);
rows.push(exc_hash);
}
}
console.log(rows);
Related
So I am having a bit of difficulty trying to think of the best way of doing this in javascript. I want to remove an array of unsorted indexes from an array that was X number of elements. For example
var index = [ 0, 7, 10, 2, 5, 11]
array = [{field0: 0}, {field1: 1}, {field2: 2}, ... {field5: 5}, {field6: 6}...]
So I tried using a nested for loop with splice, but then when I splice, my array loses its indexing and screws up.
The end result should come out to be like
array = [{field1: 1}, {field3: 3}, {field4: 4}, .... {field6: 6} ...]
Any help would be greatly appreciated.
The solution to your problem is really a one-liner:
array = [00,11,22,33,44,55,66,77];
indexes = [1,7,5,3];
array = array.filter(function(_,i) { return indexes.indexOf(i) < 0 });
document.write('<pre>'+JSON.stringify(array,0,3));
If sorting the array of elements to remove is not an issue, you can just do the following:
var array = [{field0: 0}, {field1: 1}, {field2: 2}, {field3: 3}, {field4: 4}, {field5: 5}, {field6: 6}, {field7: 7}, {field8: 8}, {field9: 9}];
var indices = [0, 7, 2, 5];
indices.sort(function(a, b) {
if ( a > b ) {
return 1;
} else if ( b > a ) {
return -1;
} else {
return 0;
}
});
for (var i = 0, offset = 0; i < indices.length; i++, offset++) {
array.splice(indices[i] - offset, 1);
}
console.log(array);
And if for some reason you were unable to sort the array of indices to remove, you could keep track of the offset with the following:
var array = [{field0: 0}, {field1: 1}, {field2: 2}, {field3: 3}, {field4: 4}, {field5: 5}, {field6: 6}, {field7: 7}, {field8: 8}, {field9: 9}];
var indices = [0, 7, 2, 5];
var removedIndices = [];
function calcOffset(val) {
var numRemoved = 0;
for (var j = 0; j < removedIndices.length; j++) {
if (val > removedIndices[j]) {
numRemoved++;
}
}
return numRemoved;
}
for (var i = 0, offset = 0; i < indices.length; i++, offset++) {
var offset = calcOffset(indices[i]);
array.splice(indices[i] - offset, 1);
removedIndices.push(indices[i]);
}
console.log(array);
I would iterate through array (for/next loop) and at each element see if the number exist in index (index.indexOf(n)). If it does, push the element to a new temporary array.
when you are done, either copy the temp array back to array OR array.length = 0 and push the elements from the temp array back onto the original array.
something like this:
var index = [ 0, 7, 10, 2, 5, 11]
var array = [{field0: 0}, {field1: 1}, {field2: 2},{field3: 3}, {field4: 4}];
var tempArray = [];
for(var arrayIndex = 0;arrayIndex < array.length;arrayIndex++){
if(index.indexOf(arrayIndex) === -1)
{
tempArray.push(array[arrayIndex]);
}
}
array = tempArray;
You can try deleting them with delete array[index[count]] by looping as long as undefined is not a problem.
Or, you can set loop through all the elements in the array and set any element whose index is not present to false. Then, loop through them again and copy only the ones which are not false to new array.
newArray = new Array();
for (var i = 0; i < array.length; i++) {
for(var j=0; j<index.length; j++) {
if (index[j] == i) {
array[i] = false;
}
}
};
for (var i = 0; i < array.length; i++) {
if (array[i] != false) {
newArray[i] = array[i];
}
}
I need to split an array into several sub arrays and replace a certain character.
First I run a function to count the number of duplicates in the array. Then I build a new array with the values and the number of instances of the value.
Code:
angular.forEach($scope.financial, function(data) {
counts[data] = (counts[data] || 0)+1;
})
Result:
[4, {25: 4}, 5, {25: 1}, 3, {10: 1}, 4, {10: 1}]
What I am looking for is to split the array into several sub arrays and replace the colon with a comma.
Like this:
[[4,25,4],[5,25,1],[3,10,1],[4,10,1]]
Any suggestions?
That can be done with a simple loop. But, some checks for the integrity of the data would be advised if you can't guarantee the format of the input.
function getKey(o) {
for (var prop in o) {
if (o.hasOwnProperty(prop)) {
return prop;
}
}
}
var data = [4, {25: 4}, 5, {25: 1}, 3, {10: 1}, 4, {10: 1}];
var i = 0;
var output = [];
var key;
for (i = 0; i < data.length; i += 2) {
key = getKey(data[i + 1]);
output.push([data[i], parseInt(key, 10), data[i + 1][key]]);
}
//Print the output
console.log(output);
var el = document.createElement('div');
el.innerHTML = JSON.stringify(output);
document.body.appendChild(el);
The below mentioned converter function will accept the reponseArray of type [4, {25: 4}, 5, {25: 1}, 3, {10: 1}, 4, {10: 1}] and converts into subarray [[4,25,4],[5,25,1],[3,10,1],[4,10,1]]
fiddle
function converter(responseArray) {
var mainArray=[], subArray;
for (var i = 0; i < responseArray.length; i++) {
if(i%2 == 0) {
subArray= [];
subArray.push(responseArray[i]);
} else {
var obj = responseArray[i];
for(var key in obj) {
subArray.push(key * 1);
subArray.push(obj[key] * 1);
}
mainArray.push(subArray);
}
}
console.log(mainArray);
return mainArray;
}
For a website I used a grid layout. What I want is to store all items per row inside a row.
I have an overall array that is calling arrWrap = [];. Now I want to create for each row an new array, where I store each time 4 items. So a new array should be created after the third item in a row.
How do I achieve this?
I use Javascript for this project.
var arrPos = [];
for (var i = 0; i < elements.length; ++i) {
arrPos[i] = i;
console.dir(arrPos[i]);
if (arrPos[i] > 3) {
alert(arrPos[i]);
};
}
var arrWrap = [];
var steps = 4;
for (var i = 0; i < elements.length; i=i+steps) {
arrWrap.push(elements.slice(i,i+steps));
}
This proposal feature the Array.prototype.reduce and offers two solutions:
Grouped by consecutive elements dataGroupedA
[
[ 0, 1, 2 ],
[ 3, 4, 5 ],
[ 6, 7, 8 ],
[ 9, 10, 11 ],
[ 12, 13, 14 ]
]
Grouped by the 5th element dataGroupedB
[
[ 0, 5, 10 ],
[ 1, 6, 11 ],
[ 2, 7, 12 ],
[ 3, 8, 13 ],
[ 4, 9, 14 ]
]
The calculation of index is the important part. The rest is standard default assignment and pushing the actual element.
var data = Array.apply(Array, { length: 15 }).map(function (_, i) { return i; }),
dataGroupedA = data.reduce(function (r, a, i) {
var index = i / 3 | 0;
r[index] = r[index] || [];
r[index].push(a);
return r;
}, []),
dataGroupedB = data.reduce(function (r, a, i) {
var index = i % 5;
r[index] = r[index] || [];
r[index].push(a);
return r;
}, []);
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(dataGroupedA, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(dataGroupedB, 0, 4) + '</pre>');
Please use the following code:
var cIndex= 0;
var data=[];
var cars = ["Saab", "Volvo", "BMW", "a", "v", "c", "q"];
for(var i = 0; i <= 3; i++)
{
cIndex = cIndex + 3;
var row = cars.slice(cIndex -3,cIndex );
data.push(row);
}
console.log(data);
I'am pretty new to JavaScript and i have this exercise that have been bugging me for a some hours now.
I want to write a Javascript function that expects an array which could contain string and/or numbers (as well as finite levels of nested arrays of strings and/or numbers), and returns a Javascript object which shows the total number of occurences of each unique values.
Something like this
var myArray = [ 1, 2, 1, 'a', [ 'd', 5, 6 ], 'A', 2, 'b', 1, 'd' ];
var myResult = myFunction( myArray );
Then it should return something like this
yourResult = {
1: 3,
2: 2,
'a': 1,
'd': 2,
5: 1,
6: 1,
'A': 1,
'b': 1,
}
So far what i have is this. I dont know how to create the object but this is not working at all. It ads all the values in the array
Array.prototype.contains = function(v) {
for(var i = 0; i < this.length; i++) {
if(this[i] === v) return true;
}
return false;
};
Array.prototype.unique = function() {
var arr = [];
for(var i = 0; i < this.length; i++) {
if(this[i] instanceof Array) {
for(var j = 0; i < this[i].length; j++){
if (!arr.contains(this[i][j])){
arr.push(this[i][j]);
}
}
}
if(!arr.contains(this[i])) {
arr.push(this[i]);
}
}
return arr;
}
var myArray = [1,3,4,2,1,[1,2,3,6],2,3,8];
var myResult = duplicates.unique();
console.log(myResult);
I would seperate it into 2 major problems:
1. Make the array members to be at one level (not nested).
2. Count repeats
The first one I solved with recursion, hope it's meet the requirements. The second is about counting instances..
Hope it's help
Fiddle example
var myArray = [ 1, 2, 1, 'a', [ 'd', 5, 6 ], 'A', 2, 'b', 1, 'd' ];
var myResult = myFunction( myArray );
console.log(myResult);
function myFunction(arr) {
var r = {};
for (var i=0 ; i < arr.length ; i++) {
if( Object.prototype.toString.call( arr[i] ) === '[object Array]' ) {
var sub = myFunction(arr[i]);
for (var attrname in sub) {
if (r[attrname])
r[attrname]++;
else {
r[attrname] = sub[attrname];
r[attrname] = 1;
}
}
}
else if (r[arr[i]])
r[arr[i]]++;
else
r[arr[i]] = 1;
}
return r;
}
An associative array is what you need to hold the result:
var associative_array={}
then you can use a function like this:
function add_to_as(value){ //Add element to the global associative array
if(associative_array[value]==undefined){
associative_array[value]=1;
}
else{
associative_array[value] +=1;//add one
}
}
function myFunction( mydata ){
for(var i = 0; i < mydata.length; i++) {
if(mydata[i] instanceof Array) { //recurse on sublists if any
myFunction(mydata[i])
}
else{
add_to_as(mydata[i]);
}
}
}
//To test the function
var myArray = [ 1, 2, 1, 'a', [ 'd', 5, 6 ], 'A', 2, 'b', 1, 'd' ];
myFunction(myArray);
console.log(associative_array);
Besides your code
you can put all the elements of your array to a second array containing all the elements of array and sub arrays. Then you can iterate over second array and find the occurrence of each element like this
var arr1 = [1, 2, 1, 'a', ['d', 5, 6], 'A', 2, 'b', 1, 'd'];
var arr = [];
var obj = {};
for (var i = 0; i < arr1.length; i++) {
if (arr1[i].length == undefined || arr1[i].length == 1) {
arr.push(arr1[i]);
}
else {
for (var j = 0; j < arr1[i].length; j++) {
arr.push(arr1[i][j]);
}
}
}
for (var i = 0, j = arr.length; i < j; i++) {
if (obj[arr[i]]) {
obj[arr[i]]++;
}
else {
obj[arr[i]] = 1;
}
}
console.log(obj);
DEMO
Updated:In case of nested arrays
var arr2 = [1, 2, 1, 'a', ['d', 5, 6,['d', 5, 6,['d', 5, 6]]], 'A', 2, 'b', 1, 'd'];
var arr = [];
var obj = {};
function singleArray(arr1) {
for (var i = 0; i < arr1.length; i++) {
if (arr1[i].length == undefined || arr1[i].length == 1) {
arr.push(arr1[i]);
}
else {
singleArray(arr1[i]);
}
}
}
singleArray(arr2);
for (var i = 0, j = arr.length; i < j; i++) {
if (obj[arr[i]]) {
obj[arr[i]]++;
}
else {
obj[arr[i]] = 1;
}
}
console.log(obj);
DEMO
I'm trying to sort an object in JS, but the sort function doesn't seem to work for my object.
I want to sort my array by frequency, descending.
["B", "A", "C", "C", "A"] will result in [C: 2, A: 2, B: 1]
Here's a fiddle: http://jsfiddle.net/64q43/
var arr = ["B", "A", "C", "C", "A"];
var arrFrequency = [];
arr.forEach(function(value) {
arrFrequency[value] = 0;
});
console.log(arrFrequency);
// [B: 0, A: 0, C: 0]
arr.filter(function(value) {
if (arrFrequency.hasOwnProperty(value)) arrFrequency[value]++;
});
console.log(arrFrequency);
// [B: 1, A: 2, C: 2]
Objects don't have any defined order. However, you can first create a an object like this:
var arr = ["B", "A", "C", "C", "A"];
var freq = {};
arr.forEach(function(value) {
freq[value] = (freq[value] || 0) + 1;
});
console.log(freq); // {B: 1, A: 2, C: 2}
And then map the keys of this object to an array:
var arrFrequency = [];
for(var k in freq) {
arrFrequency.push({ key: k, count: freq[k] });
};
console.log(arrFrequency); // [{"key":"B","count":1},{"key":"A","count":2},{"key":"C","count":2}]
And now sort it like this:
arrFrequency.sort(function(x, y) {
return y.count - x.count;
});
console.log(arrFrequency); // [{"key":"A","count":2},{"key":"C","count":2},{"key":"B","count":1}]
Demonstration
My this form of sorting function helps you:
// sort objects according to their key-names (a,b,c):
function sortObjArray(array){
for(var k=1; k < array.length; k++){
for(var i=k; i > 0; i--){
var formerLetter = Object.keys(array[i-1]);
var currLetter = Object.keys(array[i]);
if( currLetter < formerLetter ){
[x,y] = [array[i],array[i-1]];
[array[i],array[i-1]] = [y,x];
}
}
}
return array;
}
var array = [{ b: 4},{ c: 1},{ a: 3}];
sortObjArray(array);//[Object { a=3}, Object { b=4}, Object { c=1}]
// or in descending order, according to their occurrence
function sortObjArray2(array){
for(var k=1; k < array.length; k++){
for(var i=k; i > 0; i--){
var formerLetter = Object.keys(array[i-1])[0];
var currLetter = Object.keys(array[i])[0];
var formerValue = array[i-1][formerLetter];
var currValue = array[i][currLetter];
if( currValue> formerValue ){
[x,y] = [array[i],array[i-1]];
[array[i],array[i-1]] = [y,x];
}
}
}
return array;
}
var array = [{ b: 4},{ c: 1},{ a: 3}];
sortObjArray2(array);//[Object { b=4}, Object { a=3}, Object { c=1}]