Regrouping javascript array - javascript

I have the below javascript array with me
var test =[{
Maths:{
ST1:10,
ST2:2,
ST3:15}
},
{
Science:{
ST1:50,
ST3:40}
}
]
I want to generate the array shown below out of this
var t = [{ST1:{
Maths:10,
Science:50
},
ST2:{
Maths:2,
Science:0
},
ST3:{
Maths:15,
Science:40
}
}]
I tried using the code shown below
for (var key in test) {
if (test.hasOwnProperty(key)) {
for (var key1 in test[key]){
//console.log(key1)}
var abc = test[key][key1];
for(var x in abc)
{
console.log(x+key1+abc[x])
}
}
}
}
I am new to this help me doing this.

This does mostly what you want...
var t = {};
for (var i = 0; i < test.length; i++) {
for (var name in test[i]) {
for (var level in test[i][name]) {
if (!t[level])
t[level] = {}
t[level][name] = test[i][name][level]
}
}
}
Only thing missing is to get the Science:0 for when a STx value is missing under a section.
DEMO: http://jsfiddle.net/eHwBC/
Result:
{
"ST1": {
"Maths": 10,
"Science": 50
},
"ST2": {
"Maths": 2
},
"ST3": {
"Maths": 15,
"Science": 40
}
}
Keep in mind that there's no guaranteed order when using for-in for enumeration.
If the labels (Math, Science, etc) are known in advance, then you can ensure that each object gets all labels.
If not, a separate loop can be done. Depending on the approach, it could be done before or after this main loop.

Do you know about JSON.stringify(t)?
It will convert an object literal to JSON.
Mozilla's documentation of this function is available at https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify.
You can also read this blog article for further explanation

Try this:
var test =[{
Maths:{
ST1:10,
ST2:2,
ST3:15
}
},
{
Science:{
ST1:50,
ST3:40}
}
];
var result = [];
for(i = 0; i <= test.length; i++){
var resultRow = {};
for(key in test[i]){
for(subKey in test[i][key]){
if(resultRow[subKey] == undefined){
resultRow[subKey] = {};
}
resultRow[subKey][key] = test[i][key][subKey];
}
}
result.push(resultRow);
}

Try like below,
/* Iterator start */
var t = {};
for (var i = 0; i < test.length; i++) { //Iterate Maths, Science,..
for (var key in test[i]) { //Iterate Math
for (var iKey in test[i][key]) { //Iterate ST1, ST2, ST3
var s = (t.hasOwnProperty(iKey))?t[iKey]:createObject();
s[key] = test[i][key][iKey];
t[iKey] = s;
}
}
}
/* Iterator End */
p = [];
p.push(t);
//^- p is what you want
// Separate function so you can add more items later without changing logic
function createObject () {
return {'Maths' : 0, 'Science': 0};
}
DEMO and Proof below,

Related

I am stuck at a JavaScript function that should count all unique items in an array

I wanted to create a function, that counts all unique Items in an array, but somehow I do not get any output.
This is my array!
let arr = ["hi", "hello", "hi"];
And this is the code I wrote so far:
function countUnique(arr) {
var counts = {};
for (var i = 0; i < arr.length; i++) {
counts[arr[i]] = 1 + (counts[arr[i]] || 0);
}
countUnique(arr);
}
console.log(countUnique(arr));
Your are counting values correctly, however then you are calling this method recursively countUnique(arr); and it results an error of call stack exceeded.
So just remove recursive call of method countUnique(arr); and return counted value counts:
function countUnique(arr) {
var counts = {};
for (var i = 0; i < arr.length; i++) {
counts[arr[i]] = 1 + (counts[arr[i]] || 0);
}
return counts;
}
let arr = ["hi", "hello", "hi"];
console.log(countUnique(arr));
JavaScript engine limits the maximal recursion depth. We can rely on it being 10000, some engines allow more.
You could take a Set and return the size.
const countUnique = array => new Set(array).size;
console.log(countUnique(["hi", "hello", "hi"]));
let arr = ["hi", "hello", "hi"];
function countUnique(arr) {
var counts = {};
for (var i = 0; i < arr.length; i++) {
if(arr[i] in counts) {
counts[arr[i]]++;
} else {
counts[arr[i]] = 1;
}
}
return Object.keys(counts).length;
}
console.log(countUnique(arr));

Equivalent of set in ES6 to ES5

I have a set over which I am iterating in ES6. I am trying to convert it to its equivalent in ES5. My build is getting failed because of ES6. That's why I am converting it to ES5.
Here's my code in ES6
service.getDevices = function (date) {
var result = [];
var deviceList = devices[date.getTime()];
for (let item of deviceList) { // browser compatibility: support for ECMA6
result.push({"deviceName": item});
}
return result;
}
I am getting error because of 'let'. I tried using for (var item in deviceList), it does not display the charts.
I also tried this:
for(var i = 0; i < deviceList.length(); i++){
result.push({"deviceName" : deviceList[i]});
}
Even this is not working for set. can someone help and tell me how to iterate over a set in ES5 and if that is not possible, is there any equivalent way of doing it?
This is a basic set es5 class that I have used variations on over the years.
function Set(items) {
this._data = {};
this.addItems(items);
}
Set.prototype.addItem = function(value) {
this._data[value] = true;
return this;
}
Set.prototype.removeItem = function(value) {
delete this._data[value];
return this;
}
Set.prototype.addItems = function(values) {
for (var i = 0; i < values.length; i++) {
this.addItem(values[i]);
}
return this;
}
Set.prototype.removeItems = function(values) {
for (var i = 0; i < values.length; i++) {
this.removeItem(values[i]);
}
return this;
}
Set.prototype.contains = function(value) {
return !!this._data[value];
}
Set.prototype.reset = function() {
this._data = {};
return this;
}
Set.prototype.data = function() {
return Object.keys(this._data);
}
Set.prototype.each = function(callback) {
var data = this.data();
for (var i = 0; i < data.length; i++) {
callback(data[i]);
}
}
var set = new Set(['a', 'b', 'c']);
console.log(set.addItems(['a', 'd', 'e']).removeItems(['b', 'e']).data());
console.log(set.contains('a'));
console.log(set.contains('e'));
set.each(console.log)
Why not just iterate through the data and map the result with Array#map.
result = deviceList.map(function (item) {
return { deviceName: item };
});
I think your problem with your second for example is just that length is a property and not a function so you shouldn't add () to the end of it. A working version of this might look like this:
for(var i = 0; i < deviceList.length; i++){
result.push({"deviceName" : deviceList[i]});
}
This assumes (as #grabantot pointed out) that deviceList is an array, however, if it's a Set then you need to use the deviceList.size property.
However, there is a more compatible version of your first for loop which is the forEach() function (which is available on Array and Set), like this:
deviceList.forEach(function (item) {
result.push({"deviceName": item});
});

Getting leaf values from any kind of objects

I am trying to get all leaf value of any kind object as array.
Here is sample object and I want to get [1, 2, 3] from this object.
{
“group1”:[
{
“value1”:”1”,
"value2”:”2”
},
{
“gropu2”:[{
"gropu3”:”3”
}]
}]
}
Here is current implementation.
var t = {
"a":[
{
"a":"1",
"b":"2"
},
{
"d":[{
"e":"3"
}]
}]
}
function getNode( node ){
if(node == null)
return null;
if(typeof node !== 'object'){
return [node];
}
var arr = [];
for( var i = 0; i < node.length ; i ++){
Array.prototype.push.apply(arr, getNode(node[i]));
}
return arr;
}
$(document).ready(function(){
console.log(getNode(t));
});
But it is showing nothing.
I can’t understand where I am doing wrong with my implementation and is there any other easy way to get this done?
The problem is in this line.
for( var i = 0; i < node.length ; i ++){
Here you can not access all element of object using for loop.
You have to convert object to array and then do that.
var array_node = Object.keys(node).map(function(key) { return node[key] });
for( var i = 0; i < array_node.length ; i ++){
Array.prototype.push.apply(arr, getNode(array_node[i]));
}
FIDDLE

Dictionary inside array in Javascript

I have certain data sets. Example, A,B and C. There are sets of these values. For example:-
[A:asd, B:ajs, C:aknd],
[A:sdf, B:gss, C:fdss],
[A:ijq, B:cba, C:jqwd]
etc.
Now i want to make a dictionary containing these values as separate dictionaries. For example:-
{
{
A:asd,
B:ajs,
C:aknd
},
{
A:sdf,
B:gss,
C:fdss
},
{
A:ijq,
B:cba,
C:jqwd
}
}
Can someone help me out with this.
I tried doing this but it's not making a dictionary.
for( var i=0; i< n; i++) {
data += {
"A":value1,
"B":value2,
"C":value3
}
}
Any inputs?
This does not make sense in Javascript:
{
{
A:asd,
B:ajs,
C:aknd
},
{
A:sdf,
B:gss,
C:fdss
},
{
A:ijq,
B:cba,
C:jqwd
}
}
If you intend to have an object (dictionary) with integer keys, you could do it like so:
var data = {};
for( var i=0; i< n; i++) {
data[i] = {
"A":value1,
"B":value2,
"C":value3
}
}
Depending a bit on what you're trying to do, an array would likely be a better choice:
var data = [];
for( var i=0; i< n; i++) {
data.push({
"A":value1,
"B":value2,
"C":value3
});
}

Create array based on object properties

I'd like to use an object to configure some settings for an app. My idea is to start with this:
var obj = {
property_one: 3;
property_two: 2;
property_three: 1;
}
And I would like to end up with this:
var array = [
'property_one','property_one','property_one',
'property_two','property_two',
'property_three'
]
My current solution is to do this for each property:
function theConstructor(){
for(i=1; i <= obj.property_one; i++){
this.array.push('property_one');
};
for(i=1; i <= obj.property_two; i++){
this.array.push('property_two');
};
for(i=1; i <= obj.property_two; i++){
this.array.push('property_two');
};
}
But this gets tedious, because I might have many properties, and these might change as the app evolves.
I know I can loop through object's properties like this:
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
array.push(key);
}
}
But this will push the value to the array, not the key (as a string). Any ideas about how I can do this more efficiently?
Try this
function theConstructor(){
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
for(var i=1; i <= obj[key]; i++){
this.array.push(key);
};
}
}
}
Using Array.prototype.reduce():
var obj = {
property_one: 3,
property_two: 2,
property_three: 1
};
var resultArray = Object.keys(obj).reduce(function(result, curItem) {
for (var index = 0; index < obj[curItem]; index++) {
result.push(curItem);
}
return result;
}, []);
document.write(JSON.stringify(resultArray));

Categories