Create JSON string from a Map with arrays as entries - javascript

My data structure object is a Map with the following structure:
{
"2018-09-25":[0,1,2,0,8],
"2018-10-17":[0,2,0,0,0],
"2018-10-26":[0,2,1,0,0],
"2018-10-29":[0,2,2,1,0],
"2018-10-31":[0,3,2,1,0],
"2018-11-01":[0,3,3,1,0],
"2018-11-02":[0,4,4,1,0]
}
I use JSON.stringify and then JSON.parse. However, I would need the elements to be somehow named so that I can reference them (e.g. when drawing a chart).
I tried the following but I get NaN as a value.
data = Object.keys(data).map(function (k) {
return {date: new Date(k), value: +data[k]};
});
I would like to have something like this:
Key: "2018-09-25"
1:0
2:1
3:2
4:0
5:8

Since you are using map() it looks like you want an array as a final result. But, since the array will be a different size, map() doesn't really work. You can use reduce to flatten out the inner arrays into one big array:
let o = {"2018-09-25":[0,1,2,0,8],
"2018-10-17":[0,2,0,0,0],
"2018-10-26":[0,2,1,0,0],
"2018-10-29":[0,2,2,1,0],
"2018-10-31":[0,3,2,1,0],
"2018-11-01":[0,3,3,1,0],
"2018-11-02":[0,4,4,1,0]
}
let newAr = Object.entries(o).reduce((arr, [key, values]) => {
return arr.concat(values.map(n => ({date: new Date(key), value: n})))
}, [])
console.log(newAr)
Is that what you're after?

Related

Getting multi-dimensional array value using Javascript / node.js

I have an Object that looks like this>
let arr = [
['animal','lion'],
['plant','rose'],
['tree','coconut'],
]
I want to make my code look like this:
['animal','lion']
['plant','rose']
['tree','coconut']
For this, I tried this method:
let sep1=arr[0];
let sep2=arr[1];
Getting value as:
['animal','lion']
['plant','rose']
I have to repeat the code 3 time to get the output, but what if there is 30 arrays inside an object? Any solution?
Ps: I am weak in coding bear with me :slight_smile:
If you want to be able to access the separate arrays by key, you could map() through your array and create entries to create an object from. That way, you could access a specific array by property key.
let arr = [
['animal', 'lion'],
['plant', 'rose'],
['tree', 'coconut'],
];
const result = Object.fromEntries(arr.map((a, i) => {
return [`sep${i}`, a]; // return ['sepX', [x, x]] as entries
}));
console.log("result", result);
console.log("sep0", result.sep0);
console.log("sep1", result.sep1);
console.log("sep2", result.sep2);

Convert Object to JSON Object

I am using DataTables library and I have hard times in receiving data in a proper format so I am trying to adjust it before DataTable library tries to fetch data into table. I have an ajax call which returns an object of the following format:
data:[ [{ Key: "SomeKey" , Value: "SomeValue" } , { ...} ],[...] ]
And my desired output is: data:[ [{ "SomeKey":"SomeValue" } , { ...} ],[...] ]
I have tried JSON.stringify or eval method , but did not worked , also tried those 2 methods when return type was some sort of string but then it inserts \ before " so It does not convert to json. Any help or good tracks would be appreciated.
This has nothing to do with JSON. :-)
data is apparently an array of arrays of objects, where each object has properties valled Key and Value.
If you want to create a new array of arrays of objects, where the objects have a property named by the Key value whose value is the Value value, you can do that like this:
data = data.map(a => a.map(({Key,Value}) => ({[Key]: Value})));
That uses map on the arrays (both the outer and inner ones) and destructuring to pick out the Key and Value properties from each object in the subarrays, and uses computed property names to set the property name on the new object.
In ES5 and earlier, that would look like this:
data = data.map(function(a) {
return a.map(function(obj) {
var newObj = {};
newObj[obj.Key] = obj.Value;
return newObj;
});
});
You should look into Array.prototype.map (mdn)
let data = [[{Key: "SomeKey", Value: "SomeValue"}]];
let output = data.map(a => a.map(({Key, Value}) => ({[Key]: Value})));
console.log(output);
Note the [Key] syntax. To put it simply, whereas var x = 'key'; y = {x: 3} will assign the object {x: 3}, x = 'key'; y = {[x]: 3} will assign the object {key: 3}.
If you're receiving literally the string "data:[ [{ Key: "SomeKey" , Value: "SomeValue" } , { ...} ],[...] ]", then you may trim the first 5 characters ('data:') and then use JSON.parse.

Adding an conditional to create object with a TypeScript loop

So I have this loop in my code that is essentially taking an array of dates (dates) and adding each one as a key/value pair ("date":"dates[i]") to each object in my array (values).
values.forEach((obj, i) => obj.date = dates[i]);
The problem is, some of the places in my 'values' array are 'null' and I receive a 'ERROR TypeError: Cannot set property 'date' of null.'
How can I adjust for this? Is there a way using TypeScript to include a catch/conditional for those 'null' values, and to replace them with a new object containing that ("date":"dates[i]") key/value pair?
something like:
values.forEach((obj, i) =>
if (values[i]==null){
values[i]=={}
values[i].date == dates[i]
}
else {
obj.date = dates[i]
}
);
If it matters, I'm using Angular 5 components to write this to technically they are this.values and this.dates.
I'm having trouble figuring this out. Thank you!!
The behavior you want can be achieved by:
values = values.map((obj, i) => {
if (!obj) {
return {date: dates[i]};
}
obj.date = dates[i];
return obj;
});
In this situation, Array.map is more appropriate than Array.forEach, beacuse you mean to make changes to the objects on the array (Array.map returns a new object for the position at each iteration, returning a new array at the end of all the iterations).
If you use Array.forEach, you can change some property of some existing object inside your array, but you can't make something like:
values.forEach((obj, i) => {
if (!obj) {
obj = {date: dates[i]};
}
obj.date = dates[i];
});
The code inside the 'if' won't have the desired effect (the obj inside the array will be continuing to be null), as each object is merely referencing the corresponding element inside the array.

spread operator converting objects to array

I'm trying to convert a data structure like this:
data = {
0:{A:a},
1:{B:b},
2:{C:c},
}
into a structure like this:
[
{0:{A:a}},
{1:{B:b}},
{2:{C:c}},
]
Using the spread operator like this: [...data] returns any empty array.
I also tried [{...data}]
Is there a way to use the spread operator to get the desired result? Also, why doesn't this approach work?
"Is there a way to use the spread operator to get the desired result?" Short answer, no. (see below for alternate solution to what you're trying to accomplish)
"Also, why doesn't this approach work?"
It doesn't work because according to the MDN docs
"The Rest/Spread Properties for ECMAScript proposal (stage 3) adds spread properties to object literals. It copies own enumerable properties from a provided object onto a new object."
Like the docs say, according to the "Rest/Spread Properties proposal", you can't spread object properties onto an array, objects will always spread their properties onto a new object. Likewise, arrays will not spread onto an object, they will only spread onto a new array.
Alternative solution:
You can do this fairly easily with Object.keys().map(). Object.keys() will get an array of the keys of the object, and Array.map() will map them into an array of the desired structure, like so:
var data = {
0:{A:"a"},
1:{B:"b"},
2:{C:"c"},
}
var result = Object.keys(data).map(function (key) {
return { [key]: data[key] };
});
console.log(result);
You can use Object.entries to get [key, value] pairs, and map them to an array of objects using computed property names:
const data = {
0:{A: 'a'},
1:{B: 'b'},
2:{C: 'c'}
};
const result = Object.entries(data).map(([key, value]) => ({ [key]: value }));
console.log(result);
I'm afraid you cant use to spread operator like in your example, however you can produce the desired output with reduce.
data = {
0:{A:'a'},
1:{B:'b'},
2:{C:'c'},
}
let resArr = Object.keys(data).reduce((arr, e) => {
arr.push({[e]: data[e]});
return arr;
}, []);
console.log(resArr);
let data = ['Uzbek sila', 'Hikmatbet', 'Aslamboi']
let spread = [...data]
console.log(spread)

turning an array into an array with objects

I have been trying to figure out how to turn an array into an array with objects.
for example i have a json file to start with and the json file looks sorta like this
var data=[{"tasknumber":304030,
"date":"2012-05-05",
"operator":"john doe"},
{"tasknumber":23130,
"date":"2012-07-07",
"operator":"john doeeeeeeee"},
{"tasknumber":233330,
"date":"2012-08-08",
"operator":"john doe"}]
so i applied the _.countBy function that is within the underscore.js library and i get an object like this
{"john doe":2,"john doeeeeeeee":1}
ive been trying to figure out how to turn this into an array with objects so it would look something like this but i have failed in every attempt and i dont know were to start
[{operator:"john doe",
count: 2},
{operator: "john doeeeeeeee",
count:1}]
i have tried a few things but all i get is tragedy and everything breaks, does anyone know if there are any librarys or anything that could help with this sort of thing?
Given the object (not array) {"john doe":2,"john doeeeeeeee":1} as input you can get your desired output like this:
var input = {"john doe":2,"john doeeeeeeee":1};
var output = Object.keys(input).map(function(k) {
return {
operator: k,
count: input[k]
};
});
console.log(output);
Or with ES6 arrow function syntax:
var input = {"john doe":2,"john doeeeeeeee":1};
var output = Object.keys(input).map((k) => ({ operator: k, count: input[k] }) );
console.log(output);
(Note that Underscore probably provides an even shorter way to do this, but I'm not familiar with Underscore so I've just given a plain JS solution.)
Further reading:
Object.keys()
array .map()
=> arrow functions
Given your initial data array, you can just run this:
var data=[{"tasknumber":304030,
"date":"2012-05-05",
"operator":"john doe"},
{"tasknumber":23130,
"date":"2012-07-07",
"operator":"john doeeeeeeee"},
{"tasknumber":233330,
"date":"2012-08-08",
"operator":"john doe"}];
Function definition
const count = data => {
// get data in format like _.countBy
const o = data.map(x => x.operator).reduce((acc, cur) => { acc[cur] ? acc[cur] += 1 : acc[cur] = 1; return acc; }, {});
// transform object into array of object
return Object.keys(o).map(operator => ({operator, count: o[operator]}));
};
Test it by producing output
console.log(count(data));
Here is an untested underscore approach that takes your initial values as loaded from the JSON file and converts directly into your desired output format:
_.chain(input)
.groupBy(function(entry) { return entry.operator })
.map(function(entries, operator) {
return {
operator: operator,
count: entries.length
}
})
.value();

Categories