How to convert a JSON object to array of arrays - javascript

In my application I am getting a json result from the controller, which I want to turn to array of arrays in the frontend, so I can work with the google charts api.
Currently I am using a $.parseJSON(result) on the string I am getting, so in the end i get this in the console :
And what i'd like to get is :
Here is the initial json string, which i get before the parseJSON part :
[{"rolename":"some role","perc":45.5},{"rolename":"another role","perc":36.4},{"rolename":"role three","perc":9.1},{"rolename":"role four","perc":9.1}]
Any tips on how can i achieve that?

ES6 ( quite new cool stuff ):
var json=[{"rolename":"some role","perc":45.5},{"rolename":"another role","perc":36.4},{"rolename":"role three","perc":9.1},{"rolename":"role four","perc":9.1}];
var answer=json.map(el=>Object.values(el));
Working: http://jsbin.com/pejucoriqu/edit?console
ES5 ( compatible with a lot browsers):
var answer=json.map(function(el){
var arr=[];
for(var key in el){
arr.push(el[key]);
}
return arr;
});
Youve got an array of objects, And you want an array of arrays. So take each element and map it with the values of the object.

You can use map to change objects to arrays and also Object.keys and map to return only object values.
var data = [{"rolename":"some role","perc":45.5},{"rolename":"another role","perc":36.4},{"rolename":"role three","perc":9.1},{"rolename":"role four","perc":9.1}]
var result = data.map(function(e) {
return Object.keys(e).map(function(k) {
return e[k]
})
})
console.log(result)
Or with ES6 you can use arrow functions like this
var result = data.map(e => Object.keys(e).map(k => e[k]))

Related

Converting arrays nested in array into object using forEch (does not work somehow?)

I am having trouble with something i thought it will be simple.
I have an array of nested arrays with strings.
const cities = [['Vienna'],['Berlin'],['London'],['Oslo'],['New York']]
I must convert these nested arrays into objects. I think forEach method should suit perfectly along with Object.assign.
I written something like these:
function convert(element) {
Object.assign({}, element)
}
const Test = cities.forEach(convert)
But then i am getting from console.log(Test) undefinded. Why so ? I am iterating through the whole array and each of her arrays should be assign as object. Whats missing ?
Object should contain key: value pair
If you want to convert each string element into an object element. Then you can do something like this :
const cities = [['Vienna'],['Berlin'],['London'],['Oslo'],['New York']]
const res = cities.map((item) => {
return {
city: item[0]
}
});
console.log(res);

Get the value of an Element in an array

i'm trying to get the value of a Object in my array. Basically when i'm doing
var firsts = response.data;
console.log(firsts)
I have something like that
{
"EUR_BND": 1.603476
}
But the name of the object is changing every time, so i can't do
response.data.EUR_BND
I wondered if there was a way to directly get the value of the only object, without having to go through its name.
You can use the object.values
Object.values(response.data)
Which would return an array of the values in the object
Object.values(response.data)[0] would return the value if you have one
You could retrieve the keys with
Object.keys(obj)
like it is stated in the docs and then access the value like you normally would:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Try best way to get all key and value in loop
const data = {
"EUR_BND": 1.603476,
"TEST_BND": 3.4,
"TEST2_BND": 5.6
}
var key;
for (key in data) {
console.log(key+' '+data[key])
}
Using Object.values:
const data = {
"EUR_BND": 1.603476,
"TEST_BND": 3.4,
"TEST2_BND": 5.6
}
console.log(Object.values(data))
Object.values gives you a list of all values of a object keys, you can use it
<script>
data = {
"EUR_BND": 1.603476
};
value_a = Object.values(data)[0];
console.log(value_a); #1.603476
</script>
This way you don't need to use the object key to get the value
This is how you may access "EUR_BND" key within response.data or firsts object.
var firsts = response.data;
var keys = Object.keys(firsts);
console.log(firsts[keys[0]]);
I would suggest having a look at Object.keys method here
The best way for me, is to get the list of keys and then you can do whatever you want with it,
Maybe your need can evolve in the future, so it is recommended that you start by getting your keys and do the logic you wish
var keys = Object.keys(data);
if(keys && keys.length>0)
{
var firstValue = data[keys[0]];
//other staff
}

How to Concatenate Arrays of Objects and return single Array of Arrays?

I recieve 4 arrays from Geoserver. Each of these arrays contain objects holding lat lng data as here geoserver response.
I need to merge these 4 arrays in one single Array and then convert objects inside them into arrays.
This was used to structure some other response from another API:
var routes = e.routes[0].coordinates
var coords = routes.map(function(obj){
return Object.keys(obj).sort().map(function(key){
return obj[key];
})
})
This is routes and
this is coords
and coords is expected result for Geoserver response.
I get my geoserver response. structured as shown in image after I did this:
function goPark(routeLayer){
var finalRoute = routeLayer._layers;
var coordsArray = Object.keys(finalRoute).map(key => {
return finalRoute[key]
});
coordsArray.forEach(function(data){
var xy = data._latlngs;
})
If i proceed with code below I recieve arrays structured as I want, see here, but still separated. I need to merge them somehow in one single array!
var xxy = xy.map(function(obj){
return Object.keys(obj).map(function(key){
return obj[key];
})
})
There is a great npm package for this kinda task that i used once called deepmerge
You can use it to merge one or more arrays or objects into one and control the enumerable properties.
If you need lazy loading of values only when you access it, you can turn the accumulator function into a generator (for performance). There's other things you can do like using promises and a generator to yield values. Though if you aren't seeing any performance issues it's unnecessary.
function accGoPark(reset) {
return accFn(goPark, reset);
}
function accFn(fn, reset) {
const accs = accFn.accs = accFn.accs || {};
const { name } = fn;
accs[name] = !accs[name] || reset ? [] : accs[name];
accs[name] = accs[name].concat( fn() );
return accs[name];
}
You are just setting a variable xy to a reference to your last data._latlngs iterated in your forEach loop, which is why you only get the last one. You should just map coordsArray directly.
xxy = coordsArray.map(function(data){
var obj = data._latlngs;
return Object.keys(obj).map(function(key){
return obj[key];
})
})
Using Object.values, destructuring, and arrow functions to simplify syntax:
xxy = routeLayer.map( ({ _layers: { _latlngs: xy }) => Object.values(xy) );

How to avoid "Arrow function expect to return a value" error in Airbnb ESLint

I am running eslint and it is recommended to return a value whenever an arrow function(lambda function) is used. Well that makes sense. However, I come across a case that is hard to walk around.
Dict = {}
Instances = [/* an array of items where items is a dictionary that contains data */]
Instances.map((item) => {
Dict[item.name] = item.url;
});
My goal is to get the data from the Instances array and fill the dictionary Dict with it. I am using the array function to assign key value pair to the dictionary, but that violates the rule of the arrow function.
Is there any iteratools or functions other than map that would help me to achieve the goal, and avoid the rule violation?
Edit: This does not adhere to Airbnb's ES6 Style Guide.
My goal is to get the data from the Instances array and fill the dictionary with it.
Use .reduce
.. and just pass an empty object as the accumulator, filling it up as you iterate through your array.
const instances = [
{ name: 'foo', url: 'https://google.com' },
{ name: 'bar', url: 'https://stackoverflow.com' }
]
const result = instances.reduce((dict, item) => {
dict[item.name] = item.url
return dict
}, {})
console.log(result)
Why not .map?
Array.map always returns a new Array and is meant for mapping each array element to another format.
If your resulting data structure shouldn't be an Array, with the same length as the Array you are operating on, you should avoid using it.
Why .reduce instead of .forEach?
I use forEach only for doing "work" rather than transforming data. Transforming data is almost always achievable with just map and/or reduce.
Here's what I mean by "work":
const users = [userInstance, userInstance, userInstance]
users.forEach(user => user.sendEmail('Hello World'))
Use forEach instead of map.
The point of map is to modify each item in an array and put the modified versions in a new array.
forEach just runs a function on each item.
If you are looking for ES6 solution to fill dictionary object this could help and should pass ESLint also:-
const dict = Instances.reduce((map, obj) => (map[obj.name] = obj.url, map), {});
update
const dict = Instances.reduce((map, obj) => {
let mapClone = {};
mapClone = Object.assign({}, map);
mapClone[obj.name] = obj.url;
return mapClone;
}, {});

Reorder JSON with new key

I have a large JSON returned from a rest service and I need to sort it before I can use it.
Example lines:
[{"Time":"1354233600000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354234500000","Name":"NAN","TagValue":"0","TagValue2":"0.0020288255172466159"},
{"Time":"1354235400000","Name":"NAN","TagValue":"0","TagValue2":"0.0022446943714048121"},
{"Time":"1354236300000","Name":"NAN","TagValue":"0","TagValue2":"0.00014998416164500384"},
{"Time":"1354237200000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354238100000","Name":"NAN","TagValue":"0","TagValue2":"0.00015631034628383933"},
{"Time":"1354239000000","Name":"NAN","TagValue":"0","TagValue2":"1.1165024734559951E-05"}
There are about 2000 lines like this. I would like to sort them by time and get something like this:
var restData = { "1354234500000":[
{"Name":"NaN",
"TagValue":"0",
"TagValue2":"someFloat"}
{"Name:"NAN,
"TagValue":"0",
"TagVale":"0"}
],
"aNewUnixTimeStamp":[
{..........}
]};
Is there some magic javascript function that I can use to accomplish this?
var myarray = [{"Time":"1354233600000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354234500000","Name":"NAN","TagValue":"0","TagValue2":"0.0020288255172466159"},
{"Time":"1354235400000","Name":"NAN","TagValue":"0","TagValue2":"0.0022446943714048121"},
{"Time":"1354236300000","Name":"NAN","TagValue":"0","TagValue2":"0.00014998416164500384"},
{"Time":"1354237200000","Name":"NAN","TagValue":"0","TagValue2":"0"},
{"Time":"1354238100000","Name":"NAN","TagValue":"0","TagValue2":"0.00015631034628383933"},
{"Time":"1354239000000","Name":"NAN","TagValue":"0","TagValue2":"1.1165024734559951E-05"}
var result = myarray.reduce(function(res, obj) {
if (res.hasOwnProperty(obj.Time) === false) {
res[obj.Time] = [];
}
res[obj.Time].push(obj);
delete obj.Time;
return res;
}, {});
You should be aware that since the result is using the timestamps as keys of an object you won't be able to sort them since objects have no defined order.
Also .reduce() will need a shim for older browsers. You can use the one provided by MDN.
Assuming your objects are all neatly organised in an array, you can just call
bigArray.sort(function(a,b) {return a.Time < b.Time ? -1 : 1})
you can also use this pligin from jquery
http://archive.plugins.jquery.com/project/sort
$(dataSet).sort("Time", "asc");

Categories

Resources