Sort basic json object - javascript

I have a very simple json object,
{
"costA": 9617,
"costB": 11100,
"costC": 13208,
"costD": 9910
}
Is it possible to sort this json (in javascript) to get the resultant?
{
"costA": 13208,
"costB": 11100,
"costC": 9910,
"costD": 9617
}
Note: key names can change..

The below JavaScript gives the result you're after: {costA: 13208, costB: 11100, costC: 9910, costD: 9617}:
var obj = JSON.parse('{"costA": 9617, "costB": 11100, "costC": 13208, "costD": 9910}');
var values = [], keys = [], key, i;
for (key in obj) {
keys.push(key);
values.push(obj[key]);
}
values.sort(function (a, b) { return b-a; });
keys.sort();
for (i = 0; i < keys.length; ++i) {
key = keys[i];
val = values[i];
obj[key] = val;
}
console.log(obj);
See also fiddle.

Related

Nested Object Loop in JS

I'm trying to add a series of values to a nested object, having some trouble with the loop in the following code. Any help would be really appreciated.
let settings = {};
function write(id, values) {
if(!settings[id]) settings[id] = {};
for(var x = 0; x < Object.keys(values).length; x ++) {
settings[id][values[x]] = values[values[x]];
}
}
//example
write('example', {'prop1': 5, 'prop2': 10});
You're attempting to index the object values with x, which is a number. To loop through the keys of your object you can use a for...in loop:
function write(id, values) {
if(!settings[id]) settings[id] = {};
for(const key in values) {
settings[id][key] = values[key];
}
}
Another approach would be to use object destructuring:
function write(id, values) {
settings[id] = { ...(settings[id] || {}), ...values };
}
values is an object. Accessing values[x] will return undefined.
You have to access it with the correct keys in that object as below.
let settings = {};
function write(id, values) {
if (!settings[id]) settings[id] = {};
const keys = Object.keys(values);
for (var x = 0; x < keys.length; x++) {
settings[id][keys[x]] = values[keys[x]];
}
console.log(settings)
}
//example
write('example', { 'prop1': 5, 'prop2': 10 });
try to keep the Object.keys(values) return in another variable and use it to assign value in setting like this
function write(id, values) {
if(!settings[id]) settings[id] = {};
const key = Object.keys(values)
for(var x = 0; x < key.length; x ++) {
settings[id][key[x]] = values[key[x]];
}
}

Javascript (sub-) Object access by array of keys

Is it possible to set a Variable in an Object by an Array of Keys?
For example i have this Object:
var obj = {'outer': {'inner': 'value'} };
and want to set the Value selected by an Array of Keys:
var keys = ['outer', 'inner'];
to a new Value 'newValue' in order to get this Result:
obj = {'outer': {'inner': 'newValue'} };
What you can do is iterate over the array of keys, making sure that each key exists and leads to another object, until you reach the last key, which you use to set the new value.
function setVal(obj, keys, value) {
var o = obj,
len = keys.length;
// iterate through all keys, making sure each key exists and points to an object
for (var i = 0; i < len - 1; i++) {
var key = keys[i];
// check if the current key exists and is an object
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key]) {
o = o[key];
} else {
// return false or throw an error cause the key is not an object or is missing.
}
}
// update the value at the last key
o[keys[len - 1]] = value;
}
Here's a running example:
function setVal(obj, keys, value) {
var o = obj,
len = keys.length;
for (var i = 0; i < len - 1; i++) {
var key = keys[i];
if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key]) {
o = o[key];
} else {
throw new Error('Key ' + key + ' is not an object or is missing.');
}
}
o[keys[len - 1]] = value;
}
var obj = {
'outer': {
'inner': 'value'
}
};
var validKeys = ['outer', 'inner'];
var invalidKeys = ['outer', 'inner', 'extra'];
console.log('Setting valid keys');
setVal(obj, validKeys, 'new value');
console.log(obj);
console.log('Setting invalid keys');
setVal(obj, invalidKeys, 'new value');
console.log(obj);
If you want to have your method only update existing key values and not set new ones, you can wrap the last statement in setVal using hasOwnProperty:
// if object already has the last key, update its value
if (o.hasOwnProperty(keys[len - 1])) {
o[keys[len - 1]] = value;
} else {
// throw an error or return false since the last key doesn't exist.
}
The key point here is that an object property can be accessed using property name string: obj.prop <=> obj["prop"].
function SetValueByKeyNames(obj, keys, value) {
var target = obj;
for(var i = 0; i < keys.length - 1; i++) {
target = target[keys[i]];
if (!target)
return false;
}
target[keys[keys.length - 1]] = value;
return true;
}
var obj = {'outer': {'inner': 'value'} };
var keys = ['outer', 'inner'];
console.log(obj.outer.inner); // value
SetValueByKeyNames(obj, keys, 'newValue');
console.log(obj.outer.inner); // newValue

Count in an array the number for each same value

My function is
var MyArray= [];
$('input:checked').each(function(index) {
MyArray= ($(this).attr('id') + ":" + $(this).val()).length;
});
My array is
Array [ "1:R1", "2:R2", "3:R3", "4:R1" ]
I would like to count the differents values and to get this object
Object {R1:2, R2:1, R3:1}
Instead of putting the values in an array and then get the values out of the array to process them and create an object, put them in the object to start with:
var map = {};
$('input:checked').each(function() {
var key = $(this).val();
if (key in map) {
map[key]++;
} else {
map[key] = 1;
}
});
Demo: http://jsfiddle.net/Guffa/0a35c6yp/
You can convert your var with this code :
var arr = [ "1:R1", "2:R2", "3:R3", "4:R1" ];
var obj = {};
for(var i=0, l=arr.length; i<l; i++) {
var parts = arr[i].split(':');
if(parts.length > 1) {
if(!obj[parts[1]]) {
obj[parts[1]] = 0;
}
obj[parts[1]]++
}
}
console.log(obj)
Or create directly the correct object :
var obj = {};
$('input:checked').each(function (index) {
var key = $(this).val();
if (!obj[key]) {
obj[key] = 0;
}
obj[key]++
});
Use a regex to capture the correct portion of the string, and add them as keys to the object, incrementing the value if it already exists:
var regex = /\d+:(R\d+)/
var obj = {};
arr.forEach(function (el) {
var key = el.match(regex)[1];
if (!obj[key]) obj[key] = 0;
obj[key]++;
});
DEMO
You could try something like that:
Write your Array into a Map and step up your value each time your map already knows the key.
for(var i = 0; i < myArray.length; i++){
var entry = myArray[i];
var key = entry.split(":")[1];
if(myMap.has(key))
myMap.set(key, myMap.get(key) + 1);
else
myMap.set(key, 1);
}
DEMO

find value pair in json object using key element

With reference to question posted here use jQuery's find() on JSON object
I have json object in which i'd like to search value of the element if i passed respective key element to it
Json:
{"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}}
I want to retrieve value Mr.ABC when i passed Name as a key to my function
Code:
console.log(getObjects(ContextObj, 'Name'));
function getObjects(obj, key) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (i == key) {
objects.push(obj);
}
}
return objects;
}
It gives output now as
[ ]
Try this:
var data = {"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}};
function find_value(key, inner_key) {
var value = "";
$.each(data.RESPONSE, function (i, k) {
console.log(i, key, i == key)
if (i == key) {
value = k;
return false;
}
});
if (inner_key) {
if (value[inner_key]) {
value = value[inner_key];
}
}
return value;
}
Calling function:
find_value("LASTBALANCE");
find_value("CUSTOMERDETAILS", "NAME");
See DEMO here.
You need to call your code recursive for nested json keys like,
var s={"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}};
console.log(getObjects(s, 'NAME'));
console.log(getObjects(s, 'LASTBALANCE'));
function getObjects(obj, key) {
var objects = [];
for (var i in obj) {
if(typeof obj[i] == 'object'){
return getObjects(obj[i], key); // if it is an object then find the key recursively.
}
if (!obj.hasOwnProperty(i)) continue;
if (i == key) {
return obj[key];
}
}
return '';
}
Working DEMO

ways to convert array to object in my case

I face this problem a lots and I tired of writing conversion function
I can do
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
but is there short-cut for that? my case as below :
angular.forEach($scope.data, function(item){
if(thread.checked === true){
var links = item.url;
chrome.tabs.create(links, function(tab) {
});
}
});
I'm using chrome API where links is obj :
chrome.tabs.create(obj, function(tab) {
});
In an ES5 browser you can do:
var obj = {};
[0,1,2].forEach(function(v, i){obj[i] = v});
or
[0,1,2].forEach(function(v, i, arr){this[i] = v}, obj);
As a function:
function toObj(arr) {
var obj = {};
arr.forEach(function(v, i){obj[i] = v});
return obj;
}
If the object passed in may not be an array but an object with properties 0 to n, then:
function toObj(arr) {
var obj = {};
[].forEach.call(arr, function(v, i){obj[i] = v});
return obj;
}

Categories

Resources