I have the following dictionary of dictionaries, I have to use this format cuz I have no power over server side
{"1":{"aov":0,"oo":1,"ot":"Cem-Merve","pi":87},"2":{"aov":100,"oo":2,"ot":"Murat-Pelin","pi":88},"3":{"aov":0,"oo":3,"ot":"Fevzi-Azbiye","pi":85},"4":{"aov":0,"oo":4,"ot":"Burak-Gizem","pi":86},"21":{"aov":100,"oo":21,"ot":"Murat","pi":84,"ro":2},"22":{"aov":0,"oo":22,"ot":"Pelin","pi":83,"ro":2}}
I need to sort it with Javascript by keys alphabetically to be like
{"1":{"aov":0,"oo":1,"ot":"Cem-Merve","pi":87},"2":{"aov":100,"oo":2,"ot":"Murat-Pelin","pi":88},"21":{"aov":100,"oo":21,"ot":"Murat","pi":84,"ro":2},"22":{"aov":0,"oo":22,"ot":"Pelin","pi":83,"ro":2},"3":{"aov":0,"oo":3,"ot":"Fevzi-Azbiye","pi":85},"4":{"aov":0,"oo":4,"ot":"Burak-Gizem","pi":86}}
I've tried something like that but no hope:
function sortObject(o) {
var sorted = {},
key, a = [];
for (key in o) {
if (o.hasOwnProperty(key)) {
a.push(key);
}
}
a.sort();
for (key = 0; key < a.length; key++) {
sorted[a[key]] = o[a[key]];
}
return sorted;
}
any Ideas how can I perform that?
As others have pointed out in comments, an object's properties cannot be sorted. What you could do instead, is produce a sorted array of the objects properties, and iterate that array to access the objects properties in the order you wish. You basically already did this in your example code - you just tried to take it a step too far.
See jsFiddle
function getObjectKeysAlphabetical(obj) {
var keys = [],
key;
for (key in obj) {
if (obj.hasOwnProperty(key))
keys.push(key);
}
keys.sort();
return keys;
}
var obj = {}; //Your object here.
var keys = getObjectKeysAlphabetical(obj)
i = 0, key = null, val = null;
//Iterate the array of sorted keys.
for (i = 0; i < keys.length; i++) {
key = keys[i];
val = obj[key]; //Get the value of the property here.
}
Related
This question already has answers here:
Javascript equivalent of Python's zip function
(24 answers)
Closed 2 years ago.
I've an Object containing data that looks like this,
obj = {
Q1:['val1','val2'],
Q2:['val3','val4','val5'],
Q3:['val8']
}
I was trying to loop over keys and get and first element in each key concate each element in each array, and join them together using , (my object has more keys that this ofc)
So the output should be like
val1,val3,val8
val2,val4,
,val5,
I tried to loop over keys and getting each value but i think i'm missing something in my loop, as i can't change the key if it found element in each object
These are my trials below.
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
for (let i = 0; i < obj[key].length; i++) {
console.log(obj[key][i])//This is always looping on the same key but different element
}
}
}
while i want it to be something close to
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(obj[key][i])
}
}
My solution uses a deep copy of the object and then a recursive array manipulation via shift():
obj = {
Q1:['val1','val2'],
Q2:['val3','val4','val5'],
Q3:['val8']
}
var resObj = [];
function printByIndex(obj){
var newObj = JSON.parse(JSON.stringify(obj));
printByIndexHelper(newObj, 0);
}
function printByIndexHelper(obj, i){
var flag = false;
resObj[i] = [];
Object.keys(obj).forEach(function(key){
if(obj[key].length > 0){
resObj[i].push(obj[key].shift());
if(obj[key].length > 0){
flag = true;
}
}else{
resObj[i].push(null);
}
});
if(flag){
printByIndexHelper(obj, i+1);
}
}
printByIndex(obj);
console.log(resObj);
Maps over arrays and joins string. Math.max to get full length to iterate over. Uses flatMap to filter out unequal length array values.
obj = {
Q1:['val1','val2'],
Q2:['val3','val4','val5'],
Q3:['val8']
}
const o = Object.values(obj)
const len = Math.max(...o.map(({length})=>length))
console.log(
Array(len).fill().map((x,i)=>o.flatMap(q=>q[i]||[]).join(','))
)
check this same output as u require
obj = {
Q1:['val1','val2'],
Q2:['val3','val4','val5'],
Q3:['val8']
}
var keys = Object.keys(obj);
var stack = [];
var maxLength = getMaxLength(obj);
for(var k = 0; k < 3;k ++) {
var arr = [];
for(var i = 0; i<keys.length;i++) {
const key = keys[i];
const elements = obj[key];
if(k < elements.length) {
arr.push(elements[k]);
}
}
console.log(arr+"\n");
//stack.push(arr);
}
function getMaxLength(jsonObj) {
var max;
var jsonKeys = Object.keys(jsonObj);
for(var key of jsonKeys) {
const arr = jsonObj[key];
if (max == null || arr.length > max) {
max = arr.length;
}
}
return max;
}
What I am trying to do is sort an Object that includes only properties that are arrays. I am trying to sort it based on the length of the arrays. The reason I am trying to do this is so that I Object.keys() will provide a list of all names in the right order. This is my code: (I know its wrong, I cant think rn for some reason but this was my attempt.)
function sortSetsByAmount(SETS, callback) {
let n = {};
for (let i = Object.keys(SETS) - 1; i >= 0; i--) {
let biggestSets = [];
for (let j = Object.keys(SETS); j >= 0; j--) {
if (SETS[Object.keys(SETS)[i]].length > biggestSets.length) {
biggestSets = SETS[Object.keys(SETS)[i]];
}
if (j == -1) {
n[Object.keys(SETS)[i]] == biggestSets;
}
}
}
callback(n);
}
In summary, you can shallow clone the original object to a new object with sorted keys:
Object.keys(SETS) // key array of the original object
.sort((k1, k2) => SETS[k1].length - SETS[k2].length) // sort the keys compared by SETS[key] length
.reduce((cloneObj, k) => ({...cloneObj, k: SETS[k]}), {}) // shallow clone to a new object
I'm trying to use recursion in JavaScript to deeply go through an object and return its key and value.
An example of this would be:
var json2 = {
'key1': {
'key2Nested': {
'key3Nested': {
'key4Nested': 'SomeValue'
},
'key5Nested': 'unimportantValue',
'key6Nested': 'SimpleValue'
},
'key7Nested': '2SimpleValue',
'key8Nested': 'unimportantValue2'
}
};
The function will take the above input and return something like
['key1/key2Nested/key3Nested/key4Nested', 'SomeValue'],
['key1/key2Nested/key5Nested', 'unimportantValue'],
etc for all values.
The problem is I try to use a for loop on all the object's keys and I try to use recursion inside the loop. But the recursion value returns an array, which ends the for loop.
Here is the code that I have so far:
var makeArray = function(obj) {
var keysArray = Object.keys(obj);
var returnArray = [];
for (var i = 0; i < keysArray.length; i++) {
var key = keysArray[i];
var next_results;
var path, value;
if (typeof(value) != 'object' ) {
value = obj[key];
returnArray = orderedArray.concat([key, value]);
} else if (typeof(value) == "object") {
next_results = makeArray(obj[key]);
if (next_results) {
for (var j = 0; j < next_results.length; j++) {
next_results[j][1] = '/' + key + next_results[j][1];
returnArray = returnArray.concat(next_results[j]);
}
}
}
console.log(returnArray);
return returnArray;
}
}
The function needs to save the key returned from deeper recursion levels so that it can concatenate it to the path.
Perhaps my algorithm can be improved somehow or I'm thinking of it wrong. Can anyone give some advice? Thanks!
Just don't return returnArray inside the for loop body, but only after it.
Also, some other bugs:
The line
next_results[j][1] = '/' + key + next_results[j][1];
doesn't seem to be right. Your keys are in the first slot of each tuple, and you want the slash in between the keys not before them:
next_results[j][0] = key + '/' + next_results[j][0];
In
var path, value;
if (typeof(value) != 'object' ) {
value = obj[key];
you are testing the type of value before assigning it (so that you basically use the value from the previous iteration). Move the property access before the condition!
The method call
returnArray = returnArray.concat(…)
doesn't do what you think it does. You're passing in a tuple (array) that you want to get appended to the array, but the concat method merges the two arrays: [key1, value1].concat([key2, value]) == [key1, value1, key2, value2]. You want to use push instead to get an array of tuples.
In whole:
function makeArray(obj) {
var keys = Object.keys(obj);
var returnArray = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i],
value = obj[key];
if (typeof value != 'object' ) {
returnArray.push([key, value]);
} else {
var next_results = makeArray(value);
for (var j = 0; j < next_results.length; j++) {
next_results[j][0] = key + '/' + next_results[j][0];
returnArray.push(next_results[j]);
}
}
}
return returnArray;
}
I need to temporarily track the state of 5 objects in JavaScript. Each of these objects has a GUID as its id. Because of this, I was hoping to create an array of key/value pairs that I can work with. The key of each pair would be the id of each object. The value of each pair would be a boolean value. My problem is, I am really not sure how to do this in JavaScript. Currently, I have the following:
var myKeyValuePairs;
var myObjects = getMyObjects();
for (var i=0; i<myObjects.length; i++) {
var id = myObjects[i].id;
// What do I do now?
}
How do I build an array of key/value pairs in JavaScript?
var myKeyValuePairs = {},
myObjects = getMyObjects(),
i, obj
for (i=0, len = myObjects.length; i < len; i++) {
obj = myObjects[i]
myKeyValuePairs[obj.id] = obj
}
Or if you really want to use an array you could do something like
var myKeyValuePairs = getMyObjects.map(function (obj) {
return {
key: obj.id,
value: obj
}
})
I want to sort a JSON object/array (shown below as myArray), upon values from another array - very close to the MYSQL query MYSQL WHERE IN(1,2,3). I was able to get a great answer by Nick Craver on how to sort by one property and value, but how can I do this with multiple values from my other array?
Here's my dataset Json array:
var myArray = [
{
"id":"2",
"name":"My name",
"properties":{"prop1":"value1"}
}];
And the array which I want to sort upon (serialized, coming straight from a form):
var sortArray = [ { "prop1":"value1","prop2":"value2" }];
The current sorting function as it looks right now (courtesy Nick Craver):
function filterDataset(property, value){
var newArray = [];
for (var i = 0, l = myArray.length; i < l; i++) {
if (myArray[i].properties[property] === value)
newArray.push(myArray[i]);
}
return newArray;
}
Here's how I managed to fix it:
function filterDataset2(properties){
var newArray = [];
for (var i = 0, l = dataset.length; i < l; i++) {
$.each(properties, function(){
if (dataset[i].properties[this.name] === this.value)
newArray.push(myArray[i]);
});
}
return newArray;
}
This may not be what you mean, but if you have a known list of properties, could you just || your comparison? Say you have 2 properties...
function filterDataset(property, value){
var newArray = [];
for (var i = 0, l = myArray.length; i < l; i++) {
if ((dataset[i].egenskaper[property1] === value) || (dataset[i].egenskaper[property2] === value) )
newArray.push(myArray[i]);
}
return newArray;
}
Otherwise if the length of the sorting array is unknown you could use a array.find type method that will return true if the property is found within the array in question. If it returns true, just push that value on your newly sorted array.