Convert array inside JSON object into individual variables in javascript - javascript

I have a JSON object that contains two arrays. I want to convert those array elements into individual elements in the JSON object.
I need this for an input into a D3 function in javascript.
My object now:
{
0:{
start:"2016-01-01",
values:[10,11,12],
names:["a","b","c"]
},
1:{
start:"2016-01-02",
values:[25,23,50],
names:["a","b","c"]
}
}
Converted object:
{
0:{
start:"2016-01-01",
a:10,
b:11,
c:12
},
1:{
start:"2016-01-02",
a:25,
b:23,
c:50
}
}
The number of variables can vary. It won't always be 3.
Any help appreciated, Thanks

var array = {
0:{
start:"2016-01-01",
values:[10,11,12],
names:["a","b","c"]
},
1:{
start:"2016-01-02",
values:[25,23,50],
names:["x","y","z"]
}
}
convertArrayProp = ( newObject ) => {
Object.keys( array ).map( ( key ) => {
newObject[key] = {};
newObject[key]['start'] = array[key]['start'];
array[key]['names'].map( ( name, index ) => newObject[key][name] = array[key]['values'][index]);
});
return newObject;
}
console.log(convertArrayProp({}));

I know this not the best but this is one of the way to achieve what you want.
x={
0:{
start:"2016-01-01",
values:[10,11,12],
names:["a","b","c"]
},
1:{
start:"2016-01-02",
values:[25,23,50],
names:["a","b","c"]
}
}
for(y in x){
if(x.hasOwnProperty(y)){
x[y].names.forEach((key, i) => x[y][key] = x[y].values[i]);
delete x[y].names;
delete x[y].values;
}
}
console.log(x);

Related

How to check if two elements are in an object

I am trying to make a function that checks if a key ( a number ) exists in an object, and then if that element has a specific sub element. this is what I am doing
const blacklistedCities = {
[NATION_ID_USA]: [
'New York',
],
[NATION_ID_JAPAN]: [
'Tokio',
'Kyoto',
]
}
export function isBlacklistedCity(city, nationId) {
if(blacklistedCities.indexOf(nationId) !== -1 && blacklistedCities. ??WHAT SHOULD I PUT HERE??) {
return false;
}
return true;
}
NATION_ID_USA and NATION_ID_JAPAN are constants imported from another file
this function should return false when the element is found because I am using it from a filter() function somewhere else but I am open to any suggestion
thanks
I'd think of the input object as describing a much simpler array of scalar values that will be queried.
// Convert the input to a set containing [ 'nationId-cityId', ...]
//
const blacklistedCities = {
NATION_ID_USA: [
'New York',
],
NATION_ID_JAPAN: [
'Tokio',
'Kyoto',
]
}
const keys = Object.entries(blacklistedCities).reduce((acc, [nationId, cityIdArray]) => {
let nationIds = cityIdArray.map(cityId => `${nationId}-${cityId}`)
acc = acc.concat(nationIds)
return acc
}, [])
// keep this set around for queries
const queryMe = new Set(keys)
// and query with nation, key pair
function queryFor(nationId, cityId) {
return queryMe.has(`${nationId}-${cityId}`)
}
console.log(queryFor('NATION_ID_USA', 'New York')) // -> true
console.log(queryFor('NATION_ID_FRANCE', 'Paris')) // -> false
You can use the nation name as a property name to index directly into the object, and then use .includes() on the array (if present):
export function isBlacklistedCity(city, nationId) {
return (nationId in blacklistedCitites) && blacklistedCities[nationId].includes(city);
}
You can do something like this
const blacklistedCities = {
NATION_ID_USA: [
'New York',
],
NATION_ID_JAPAN: [
'Tokio',
'Kyoto',
]
}
function isBlacklistedCity(city, nationId) {
if(blacklistedCities[nationId] && blacklistedCities[nationId].length > 0 && blacklistedCities[nationId].find((cityInObj) => cityInObj==city)) {
return true;
} else {
return false;
}
}
console.log(isBlacklistedCity("Tokio", "NATION_ID_JAPAN"));

Javascript - Sort array with lodash - Get key from inital variable

I'm sure, this is a simple question, but actually I can't find a solution. Maybe someone can give me hint.
I have this type of Object array:
const Country = {
albania:
{
'iso':'al',
'countryNo': 70,
'name':
{
de: 'Albanien',
en: 'Albania',
pl: 'Albania',
},
'flag':'flag-icon-al',
'showCountry':true,
},
austria:
{
'iso':'at',
'countryNo': 38,
'name':
{
de: 'Österreich',
en: 'Austria',
pl: 'Austria',
},
'flag':'flag-icon-at',
'showCountry':true,
},
belgium:
{
'iso':'be',
'countryNo': 2,
'name':
{
de: 'Belgien',
en: 'Belgium',
pl: 'Belgia',
},
'flag':'flag-icon-be',
'showCountry':true,
},
...
The keys of this object are albania, austria, etc.
Now I want to sort the array. This I'm doing with lodash sortBy function.
let countryList = _.sortBy(Country,'name[' + this.props.currentLanguage + ']');
When I iterate through the countryList array, how can I get the original keys from the Country object array, i.e. albania?
I tried to work with map function, but then I only get keys named 0, 1 etc.
countryList.map((country,key) => {
// country -> has all object information
// key -> 0, 1, 2 etc.
})
See the debug picture:
UPDATE
Is there any better solution than this:
countryList.map((country,key) => {
var key = Object.keys(Country).find(function(element) {
const countryInner = Country[element];
if(countryInner.countryNo === country.countryNo) {
return element;
}
});
if(country.showCountry === true) {
return (
<HashLink to="/#locations" className={"dropdown-item imageLink animated"} onClick={(e) => this.handleClickCountry(e, key)} key={"nav" + key}>{country.name[this.props.currentLanguage].toUpperCase()}</HashLink>
);
}
})
The solution i will suggest is instead of using lodash , create a 2d array out of your object.Basically move them to an array, sort that array and then rebuild
var countryList = [];
for (var con in Country) {
countryList.push([con, Country[con]]);
}
//Sort based on key value
sortable.sort(function(a, b) {
return a[0] > b[0];
});
Once you have the array, you could rebuild the object from the array in the order you like. By this your key wont be lost and you don't have to iterate twice to find that.
Hope it helps
When you sort your collection you will lose your object keys, so if it is important for you to keep them after sorting you can add these keys into objects as property you can do it with map
let countries = _.map(Country, (country, key) => {
country.key = key;
return country;
});
Now we can sort array again with sortBy method of lodash
let orderedCountries = _.sortBy(countries, function (country) {
return country.name[lang]
});
where lang is one of your language ('de'm 'en', 'pl')...
I believe you also want to filter your list depends on their showCountry property so lets merge all of them...
function sortAndFilterCountries(countries, lang) {
countries = _.map(countries, (country, key) => {
country.key = key;
return country;
});
let orderedCountries = _.sortBy(countries, function (country) {
return country.name[lang]
});
return _.filter(orderedCountries, 'showCountry');
}

Convert dynamic string to JSON using javascript

I am using API that its response contains dynamic array of strings as the following:
var arr = ["Request.name","Request.name.first","Request.name.first.last"]; //response 3
so i want to convert it dynamically to array of JSON objects like this:
var arrayOfObjects = [
{
"Request": {
"name":val
}
} //converted from arr[0]
,{
"Request": {
"name":{
"first":val
}
}
} //converted from arr[1]
,{
"Request": {
"name":{
"first":{
"last":val
}
}
}
} //converted from arr[2]
];
and so on...
is this possible?
You can create a function that converts a dot-separated string into a respective deeply nested object, then map your input array of strings with it. My solution is iterative, though I think it can be done recursively as well.
var arr = ["Request.name","Request.name.first","Request.name.first.last"];
function createObjFromStr(str) {
return str.split('.').reduceRight((all, key, i, arr) => {
if (i === arr.length - 1) {
all = {[key]: 0};
} else {
all[key] = Object.assign({}, all);
Object.keys(all).forEach(k => {
if (k !== key) delete all[k];
});
}
return all;
}, {});
}
const arrayOfObjects = arr.map(createObjFromStr);
console.log(arrayOfObjects);

Parsing a value from JSON response that keeps changing order

Im trying to parse JSON response from my home automation system in javscript.
The response is
available here
That is only a small part of the response, also, the order of keys changes on every reboot for reasons i do not know, su using the the number index wont really work
i need to be able to store the state value of sensor.out, sensor.in, sensor.door into variables for tasker on andorid
i tried to select using the entity.id, but for some reason the code never finished ( i believe i just didnt know what i was doing)
With ES6 you can use the Array#find method:
response.find(o => o.entity_id == 'sensor.out').state
See snippet:
var response = [ { "attributes":{ "friendly_name":"door" }, "entity_id":"sensor.door", "last_changed":"2016-12-31T11:15:59.395808+00:00", "last_updated":"2016-12-31T11:15:59.395808+00:00", "state":"closed" }, { "attributes":{ "friendly_name":"In", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.in", "last_changed":"2016-12-31T11:20:02.179821+00:00", "last_updated":"2016-12-31T11:20:02.179821+00:00", "state":"20.7" }, { "attributes":{ "changed_by":null, "code_format":".+", "friendly_name":"panel" }, "entity_id":"alarm_control_panel.panel", "last_changed":"2016-12-31T11:14:56.471966+00:00", "last_updated":"2016-12-31T11:14:56.471966+00:00", "state":"disarmed" }, { "attributes":{ "friendly_name":"Out", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.out", "last_changed":"2016-12-31T11:14:58.452345+00:00", "last_updated":"2016-12-31T11:14:58.452345+00:00", "state":"7.1" }];
var state = response.find(o => o.entity_id == 'sensor.out').state;
console.log('sensor.out state is', state);
Alternatively, you could convert the response to an object with the entity id values as keys, so you can access it like response['session.out'].state:
response = Object.assign({}, ...response.map( o => ({[o.entity_id]: o}) ));
See snippet:
var response = [ { "attributes":{ "friendly_name":"door" }, "entity_id":"sensor.door", "last_changed":"2016-12-31T11:15:59.395808+00:00", "last_updated":"2016-12-31T11:15:59.395808+00:00", "state":"closed" }, { "attributes":{ "friendly_name":"In", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.in", "last_changed":"2016-12-31T11:20:02.179821+00:00", "last_updated":"2016-12-31T11:20:02.179821+00:00", "state":"20.7" }, { "attributes":{ "changed_by":null, "code_format":".+", "friendly_name":"panel" }, "entity_id":"alarm_control_panel.panel", "last_changed":"2016-12-31T11:14:56.471966+00:00", "last_updated":"2016-12-31T11:14:56.471966+00:00", "state":"disarmed" }, { "attributes":{ "friendly_name":"Out", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.out", "last_changed":"2016-12-31T11:14:58.452345+00:00", "last_updated":"2016-12-31T11:14:58.452345+00:00", "state":"7.1" }];
response = Object.assign({}, ...response.map( o => ({[o.entity_id]: o}) ));
console.log('sensor.out state is', response['sensor.out'].state);
If you're trying to uses indexes to select properties from objects, you shouldn't be, unless there is a very specific reason to do so.
Fortunately that's fine, you don't need to know the order. I took two of the objects from your JSON array, scrambled up the properties, and wrote a function that returns any object that contains the key/val you specify.
Your question is a little hard to follow, but I think this will give you the idea.
<script type="text/javascript">
let arr = [
{
"attributes":{
"friendly_name":"door"
},
"entity_id":"sensor.frontdoor",
"last_changed":"2016-12-31T11:15:59.395808+00:00",
"last_updated":"2016-12-31T11:15:59.395808+00:00",
"state":"closed"
},
{
"last_changed":"2016-12-31T11:15:59.395808+00:00",
"state":"closed",
"attributes":{
"friendly_name":"door"
},
"entity_id":"sensor.backdoor",
"last_updated":"2016-12-31T11:15:59.395808+00:00"
}
];
function findKey ( theKey, theVal ) {
let reduced = arr.filter ( d => {
return d [ theKey ] === theVal;
});
return reduced;
}
let targets = findKey ( 'entity_id', 'sensor.backdoor' );
targets.forEach ( d => {
// This check is a little naive, but should give you the idea
if ( 'state' in d ) {
console.log ( d.state );
}
} );
</script>
What everyone says is correct: The order of keys in the response doesn't matter. Use the (string) key, not a numerical index.
var arr = [
{
"entity_id":"sensor.door",
"state":"closed"
}]; // other attributes chopped out for brevity
var entity_id_interested_in = 'sensor.door';
var state = '[entity_id not found in response]';
for (var i = 0; i < arr.length; i++) {
console.log(arr[i].entity_id + ' state:' + arr[i].state);
if (arr[i].entity_id == entity_id_interested_in)
{
state = arr[i].state;
break;
}
}
console.log (state);

Return JSON properties

I am trying to return my JSON object's properties. My JSON file object looks like:
{ Products:
{
'Cars': { tableFields: [Object] },
'Planes': { tableFields: [Object] }
}
}
I am trying to return an array that contains Products' attributes - Cars and Planes. For example - I want the end result to be the following array:
['Cars', 'Planes']
Can someone help?
Thanks!
You can use Object.keys() function:
var data = {
Products: {
'Cars': {
tableFields: [ Object ]
},
'Planes': {
tableFields: [ Object ]
}
}
};
var result = Object.keys(data.Products);
console.log(result);
var keys = [];
for ( var key in Products )
{
//We only want the direct properties
if ( Products.hasOwnProperty( key ) ) keys[ keys.length ] = key;
}

Categories

Resources