Converting an object literal to a sorted Array - javascript

I have an object literal, where the values of its key are more objects, and one of the keys of the inner objects is named "rank" - and has an floating point value. I want to convert the object literal to an array of the inner objects, sorted by the value of "rank".
Input Object:
{
452:{
bla:123,
dff:233,
rank:2
},
234:{
bla:123,
dff:233,
rank:1
}
}
Output Array:
[
{ bla:123, dff:233, rank:1},
{ bla:123, dff:233, rank:2 }
]

Example:
var data = {
foo: {
rank: 5
},
bar: {
rank: 2
},
baz: {
rank: 8
}
};
Javascript:
var mappedHash = Object.keys( data ).sort(function( a, b ) {
return data[ a ].rank - data[ b ].rank;
}).map(function( sortedKey ) {
return data[ sortedKey ];
});
That would first sort the inner objects by the value of obj.rank and after that map the containing objects into an Array.
Result: [{rank: 2}, {rank: 5}, {rank: 8}]
Reference: Object.keys, Array.prototype.sort, Array.prototype.map
The above code contains ECMAscript 262 edition 5 code, which is available in all modern browsers. If you want to support legacy browsers as well, you need to include one of the various ES5-Shim libraries.

Iterate over your object's properties, pushing the inner objects into an array, and then sort the array with a custom sort function:
var inputObject = {}, // your object here
arr = [];
for (var k in inputObject)
arr.push(inputObject[k]);
arr.sort(function(a,b) { return a.rank - b.rank; });

Related

NODEJS - Prevent duplicate keys from being added into an object array

I have a function I am trying to use to not add duplicates (Later on will combine)
function arrayCombine(arrayOfValues, arrayOfValues2) {
for (var arrName in arrayOfValues2) {
if (arrayOfValues.indexOf(arrName)==-1) arrayOfValues.push([arrName, arrayOfValues2[arrName]]);
}
return arrayOfValues;
}
The arrays are lets say:
arrayOfValues
[
[ 'test', 11 ],
[ 'test2', 13 ],
[ 'test3', 16 ],
]
arrayOfValues2
[
[ 'test4', 12 ],
[ 'test2', 25 ],
]
When I try to combine these, it does NOT remove the duplicate test2 here. It pushes it anyways.
This does not occur if the number does not exist so I assume when I'm checking for INDEXOF, there has to be a way to check for only the named value and not the numbered value too. What I mean is:
function arrayCombine(arrayOfValues, arrayOfValues2) {
for (var arrName in arrayOfValues2) {
if (arrayOfValues.indexOf(arrName)==-1) arrayOfValues.push(arrName);
}
return arrayOfValues;
}
Did work originally.
How can I have it only 'check' the name? In the future I will also combine but for now I just want to make sure no duplicate names get added.
Since objects only allow unique keys it may be simpler to use one to collate your data from both arrays. By concatenating the arrays, and then reducing over them to create an object, you can add/combine each nested arrays values as you see fit. Then, to get an array back from the function use Object.values on the object.
const arr1=[["test",11],["test2",13],["test3",16]],arr2=[["test4",12],["test2",25]];
// Accepts the arrays
function merge(arr1, arr2) {
// Concatentate the arrays, and reduce over that array
const obj = arr1.concat(arr2).reduce((acc, c) => {
// Destructure the "key" and "value" from the
// nested array
const [ key, value ] = c;
// If the "key" doesn't exist on the object
// create it and assign an array to it, setting
// the second element to zero
acc[key] ??= [ key, 0 ];
// Increment that element with the value
acc[key][1] += value;
// Return the accumulator for the next iteration
return acc;
}, {});
// Finally return only the values of the object
// which will be an array of arrays
return Object.values(obj);
}
console.log(merge(arr1, arr2));
Additional documentation
Logical nullish assignment
Destructuring assignment

ES6 for-of loop in map key value [duplicate]

This question already has answers here:
How do I loop through or enumerate a JavaScript object?
(48 answers)
Closed last year.
I have a dictionary that has the format of
dictionary = {0: {object}, 1:{object}, 2:{object}}
How can I iterate through this dictionary by doing something like
for ((key, value) in dictionary) {
//Do stuff where key would be 0 and value would be the object
}
tl;dr
In ECMAScript 2017, just call Object.entries(yourObj).
In ECMAScript 2015, it is possible with Maps.
In ECMAScript 5, it is not possible.
ECMAScript 2017
ECMAScript 2017 introduced a new Object.entries function. You can use this to iterate the object as you wanted.
'use strict';
const object = {'a': 1, 'b': 2, 'c' : 3};
for (const [key, value] of Object.entries(object)) {
console.log(key, value);
}
Output
a 1
b 2
c 3
ECMAScript 2015
In ECMAScript 2015, there is not Object.entries but you can use Map objects instead and iterate over them with Map.prototype.entries. Quoting the example from that page,
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
var mapIter = myMap.entries();
console.log(mapIter.next().value); // ["0", "foo"]
console.log(mapIter.next().value); // [1, "bar"]
console.log(mapIter.next().value); // [Object, "baz"]
Or iterate with for..of, like this
'use strict';
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
for (const entry of myMap.entries()) {
console.log(entry);
}
Output
[ '0', 'foo' ]
[ 1, 'bar' ]
[ {}, 'baz' ]
Or
for (const [key, value] of myMap.entries()) {
console.log(key, value);
}
Output
0 foo
1 bar
{} baz
ECMAScript 5:
No, it's not possible with objects.
You should either iterate with for..in, or Object.keys, like this
for (var key in dictionary) {
// check if the property/key is defined in the object itself, not in parent
if (dictionary.hasOwnProperty(key)) {
console.log(key, dictionary[key]);
}
}
Note: The if condition above is necessary only if you want to iterate over the properties which are the dictionary object's very own. Because for..in will iterate through all the inherited enumerable properties.
Or
Object.keys(dictionary).forEach(function(key) {
console.log(key, dictionary[key]);
});
Try this:
dict = {0:{1:'a'}, 1:{2:'b'}, 2:{3:'c'}}
for (var key in dict){
console.log( key, dict[key] );
}
0 Object { 1="a"}
1 Object { 2="b"}
2 Object { 3="c"}
WELCOME TO 2020 *Drools in ES6*
Theres some pretty old answers in here - take advantage of destructuring. In my opinion this is without a doubt the nicest (very readable) way to iterate an object.
const myObject = {
nick: 'cage',
phil: 'murray',
};
Object.entries(myObject).forEach(([k,v]) => {
console.log("The key: ", k)
console.log("The value: ", v)
})
Edit:
As mentioned by Lazerbeak, map allows you to cycle an object and use the key and value to make an array.
const myObject = {
nick: 'cage',
phil: 'murray',
};
const myArray = Object.entries(myObject).map(([k, v]) => {
return `The key '${k}' has a value of '${v}'`;
});
console.log(myArray);
Edit 2:
To explain what is happening in the line of code:
Object.entries(myObject).forEach(([k,v]) => {}
Object.entries() converts our object to an array of arrays:
[["nick", "cage"], ["phil", "murray"]]
Then we use forEach on the outer array:
1st loop: ["nick", "cage"]
2nd loop: ["phil", "murray"]
Then we "destructure" the value (which we know will always be an array) with ([k,v]) so k becomes the first name and v becomes the last name.
The Object.entries() method has been specified in ES2017 (and is supported in all modern browsers):
for (const [ key, value ] of Object.entries(dictionary)) {
// do something with `key` and `value`
}
Explanation:
Object.entries() takes an object like { a: 1, b: 2, c: 3 } and turns it into an array of key-value pairs: [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ].
With for ... of we can loop over the entries of the so created array.
Since we are guaranteed that each of the so iterated array items is itself a two-entry array, we can use destructuring to directly assign variables key and value to its first and second item.
Try this:
var value;
for (var key in dictionary) {
value = dictionary[key];
// your code here...
}
You can do something like this :
dictionary = {'ab': {object}, 'cd':{object}, 'ef':{object}}
var keys = Object.keys(dictionary);
for(var i = 0; i < keys.length;i++){
//keys[i] for key
//dictionary[keys[i]] for the value
}
I think the fast and easy way is
Object.entries(event).forEach(k => {
console.log("properties ... ", k[0], k[1]); });
just check the documentation
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
using swagger-ui.js
you can do this -
_.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
console.log(n, key);
});
You can use below script.
var obj={1:"a",2:"b",c:"3"};
for (var x=Object.keys(obj),i=0;i<x.length,key=x[i],value=obj[key];i++){
console.log(key,value);
}
outputs
1 a
2 b
c 3
As an improvement to the accepted answer, in order to reduce nesting, you could do this instead, provided that the key is not inherited:
for (var key in dictionary) {
if (!dictionary.hasOwnProperty(key)) {
continue;
}
console.log(key, dictionary[key]);
}
Edit: info about Object.hasOwnProperty here
You can use JavaScript forEach Loop:
myMap.forEach((value, key) => {
console.log('value: ', value);
console.log('key: ', key);
});

How to iterate (keys, values) in JavaScript? [duplicate]

This question already has answers here:
How do I loop through or enumerate a JavaScript object?
(48 answers)
Closed last year.
I have a dictionary that has the format of
dictionary = {0: {object}, 1:{object}, 2:{object}}
How can I iterate through this dictionary by doing something like
for ((key, value) in dictionary) {
//Do stuff where key would be 0 and value would be the object
}
tl;dr
In ECMAScript 2017, just call Object.entries(yourObj).
In ECMAScript 2015, it is possible with Maps.
In ECMAScript 5, it is not possible.
ECMAScript 2017
ECMAScript 2017 introduced a new Object.entries function. You can use this to iterate the object as you wanted.
'use strict';
const object = {'a': 1, 'b': 2, 'c' : 3};
for (const [key, value] of Object.entries(object)) {
console.log(key, value);
}
Output
a 1
b 2
c 3
ECMAScript 2015
In ECMAScript 2015, there is not Object.entries but you can use Map objects instead and iterate over them with Map.prototype.entries. Quoting the example from that page,
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
var mapIter = myMap.entries();
console.log(mapIter.next().value); // ["0", "foo"]
console.log(mapIter.next().value); // [1, "bar"]
console.log(mapIter.next().value); // [Object, "baz"]
Or iterate with for..of, like this
'use strict';
var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");
for (const entry of myMap.entries()) {
console.log(entry);
}
Output
[ '0', 'foo' ]
[ 1, 'bar' ]
[ {}, 'baz' ]
Or
for (const [key, value] of myMap.entries()) {
console.log(key, value);
}
Output
0 foo
1 bar
{} baz
ECMAScript 5:
No, it's not possible with objects.
You should either iterate with for..in, or Object.keys, like this
for (var key in dictionary) {
// check if the property/key is defined in the object itself, not in parent
if (dictionary.hasOwnProperty(key)) {
console.log(key, dictionary[key]);
}
}
Note: The if condition above is necessary only if you want to iterate over the properties which are the dictionary object's very own. Because for..in will iterate through all the inherited enumerable properties.
Or
Object.keys(dictionary).forEach(function(key) {
console.log(key, dictionary[key]);
});
Try this:
dict = {0:{1:'a'}, 1:{2:'b'}, 2:{3:'c'}}
for (var key in dict){
console.log( key, dict[key] );
}
0 Object { 1="a"}
1 Object { 2="b"}
2 Object { 3="c"}
WELCOME TO 2020 *Drools in ES6*
Theres some pretty old answers in here - take advantage of destructuring. In my opinion this is without a doubt the nicest (very readable) way to iterate an object.
const myObject = {
nick: 'cage',
phil: 'murray',
};
Object.entries(myObject).forEach(([k,v]) => {
console.log("The key: ", k)
console.log("The value: ", v)
})
Edit:
As mentioned by Lazerbeak, map allows you to cycle an object and use the key and value to make an array.
const myObject = {
nick: 'cage',
phil: 'murray',
};
const myArray = Object.entries(myObject).map(([k, v]) => {
return `The key '${k}' has a value of '${v}'`;
});
console.log(myArray);
Edit 2:
To explain what is happening in the line of code:
Object.entries(myObject).forEach(([k,v]) => {}
Object.entries() converts our object to an array of arrays:
[["nick", "cage"], ["phil", "murray"]]
Then we use forEach on the outer array:
1st loop: ["nick", "cage"]
2nd loop: ["phil", "murray"]
Then we "destructure" the value (which we know will always be an array) with ([k,v]) so k becomes the first name and v becomes the last name.
The Object.entries() method has been specified in ES2017 (and is supported in all modern browsers):
for (const [ key, value ] of Object.entries(dictionary)) {
// do something with `key` and `value`
}
Explanation:
Object.entries() takes an object like { a: 1, b: 2, c: 3 } and turns it into an array of key-value pairs: [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ].
With for ... of we can loop over the entries of the so created array.
Since we are guaranteed that each of the so iterated array items is itself a two-entry array, we can use destructuring to directly assign variables key and value to its first and second item.
Try this:
var value;
for (var key in dictionary) {
value = dictionary[key];
// your code here...
}
You can do something like this :
dictionary = {'ab': {object}, 'cd':{object}, 'ef':{object}}
var keys = Object.keys(dictionary);
for(var i = 0; i < keys.length;i++){
//keys[i] for key
//dictionary[keys[i]] for the value
}
I think the fast and easy way is
Object.entries(event).forEach(k => {
console.log("properties ... ", k[0], k[1]); });
just check the documentation
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
using swagger-ui.js
you can do this -
_.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
console.log(n, key);
});
You can use below script.
var obj={1:"a",2:"b",c:"3"};
for (var x=Object.keys(obj),i=0;i<x.length,key=x[i],value=obj[key];i++){
console.log(key,value);
}
outputs
1 a
2 b
c 3
As an improvement to the accepted answer, in order to reduce nesting, you could do this instead, provided that the key is not inherited:
for (var key in dictionary) {
if (!dictionary.hasOwnProperty(key)) {
continue;
}
console.log(key, dictionary[key]);
}
Edit: info about Object.hasOwnProperty here
You can use JavaScript forEach Loop:
myMap.forEach((value, key) => {
console.log('value: ', value);
console.log('key: ', key);
});

Get the Common and Uniques Elements Comparing two or more arrays in Javascript

First of all i check a lot of post, like this:
Finding matches between multiple JavaScript Arrays
How to merge two arrays in Javascript and de-duplicate items
Unique values in an array
All these works fine but only with arrays that contain integers or strings, i need that works for whatever you want.
i have two arrays, and want to storage in a new array the unique elements, and in other array the common elements.
These elements could be; variables, arrays, strings, hash (objects) functions, integers, float numbers or boolean
And probably never gonna be a duplicate value inside of the arrays.
Would be awesome with plain JS
And i don't care about IE (but would be nice for others i guess), so if there is a new ES6 way, i gonna love it , i care more about performance :)
// Some values that gonna be inside the array1 & array2
function random(){};
var a = 5,
b = {};
// The Arrays
var array1 = [0,1,2,3, "HeLLo", "hello", 55.32, 55.550, {key: "value", keyWithArray: [1,2,3]}, random, a, b];
var array2 = [2,3, "hello", "Hello", 55.32, 55.551, {key: "value", keyWithArray: [1,2,3]}, b];
// The Unique Array should be all the elements that array1 have and array2 haven't
var uniqueArray = [0, 1, "HeLLo", 55.550, random, a];
// The commonArray should the common elements in both arrays (array1 and array2)
var commonArray = [2,3, "hello", 55.32, {key: "value", keyWithArray: [1,2,3]}, b]
// I try something like this but doesn't work
var uniqueArray = array1.filter(function(val) { return array2.indexOf(val) == -1; });
console.log(uniqueArray);
From what I understood you basically want to perform some set operations on your two arrays. My suggestion is to first build a more appropriate data structure from your two arrays, because to do something like get the intersection of both you would have to do an O(n²) algorithm.
Something like this should do it:
// convert a plain array that has values of mixed types to and object
// where the keys are the values in plain form in case of strings, scalars or functions, or serialized objects in
// case of objects and arrays, and where the values are the unaltered values of the array.
var _toObject = function(arr) {
var obj = {};
for (var i=0 ; i<arr.length ; i++) {
var el = arr[i];
var type = typeof el;
if (type !== 'object') { // scalars, strings and functions can be used as keys to an array
obj[el] = el;
}
else { // objects and arrays have to be serialized in order to be used as keys
obj[JSON.stringify(el)] = el;
}
};
return obj;
};
var objArray1 = _toObject(array1);
var objArray2 = _toObject(array2);
var uniqueArray = [];
var commonArray = [];
for (var i in objArray1) {
if (i in objArray2) {
commonArray.push(objArray1[i]); // push the common elements
delete objArray2[i]; // delete so in the end objArray2 will only have unique elements
}
else {
uniqueArray.push(objArray1[i]); // push unique element from objArray1
}
}
for (var i in objArray2) { // now objArray2 has only unique values, just append then to uniqueArray
uniqueArray.push(objArray2[i])
}
console.log('Unique array', uniqueArray);
console.log('Common array', commonArray);
this should give you the desired result:
bash-4.2$ node test.js
Unique array [ 0, 1, 5, 'HeLLo', 55.55, [Function: random], 'Hello', 55.551 ]
Common array [ 2, 3, 'hello', 55.32, { key: 'value', keyWithArray: [1, 2, 3 ] }, {}]

Best way to store a key=>value array in JavaScript?

What's the best way to store a key=>value array in javascript, and how can that be looped through?
The key of each element should be a tag, such as {id} or just id and the value should be the numerical value of the id.
It should either be the element of an existing javascript class, or be a global variable which could easily be referenced through the class.
jQuery can be used.
That's just what a JavaScript object is:
var myArray = {id1: 100, id2: 200, "tag with spaces": 300};
myArray.id3 = 400;
myArray["id4"] = 500;
You can loop through it using for..in loop:
for (var key in myArray) {
console.log("key " + key + " has value " + myArray[key]);
}
See also: Working with objects (MDN).
In ECMAScript6 there is also Map (see the browser compatibility table there):
An Object has a prototype, so there are default keys in the map. This could be bypassed by using map = Object.create(null) since ES5, but was seldomly done.
The keys of an Object are Strings and Symbols, where they can be any value for a Map.
You can get the size of a Map easily while you have to manually keep track of size for an Object.
If I understood you correctly:
var hash = {};
hash['bob'] = 123;
hash['joe'] = 456;
var sum = 0;
for (var name in hash) {
sum += hash[name];
}
alert(sum); // 579
You can use Map.
A new data structure introduced in JavaScript ES6.
Alternative to JavaScript Object for storing key/value pairs.
Has useful methods for iteration over the key/value pairs.
var map = new Map();
map.set('name', 'John');
map.set('id', 11);
// Get the full content of the Map
console.log(map); // Map { 'name' => 'John', 'id' => 11 }
Get value of the Map using key
console.log(map.get('name')); // John
console.log(map.get('id')); // 11
Get size of the Map
console.log(map.size); // 2
Check key exists in Map
console.log(map.has('name')); // true
console.log(map.has('age')); // false
Get keys
console.log(map.keys()); // MapIterator { 'name', 'id' }
Get values
console.log(map.values()); // MapIterator { 'John', 11 }
Get elements of the Map
for (let element of map) {
console.log(element);
}
// Output:
// [ 'name', 'John' ]
// [ 'id', 11 ]
Print key value pairs
for (let [key, value] of map) {
console.log(key + " - " + value);
}
// Output:
// name - John
// id - 11
Print only keys of the Map
for (let key of map.keys()) {
console.log(key);
}
// Output:
// name
// id
Print only values of the Map
for (let value of map.values()) {
console.log(value);
}
// Output:
// John
// 11
In javascript a key value array is stored as an object. There are such things as arrays in javascript, but they are also somewhat considered objects still, check this guys answer - Why can I add named properties to an array as if it were an object?
Arrays are typically seen using square bracket syntax, and objects ("key=>value" arrays) using curly bracket syntax, though you can access and set object properties using square bracket syntax as Alexey Romanov has shown.
Arrays in javascript are typically used only with numeric, auto incremented keys, but javascript objects can hold named key value pairs, functions and even other objects as well.
Simple Array eg.
$(document).ready(function(){
var countries = ['Canada','Us','France','Italy'];
console.log('I am from '+countries[0]);
$.each(countries, function(key, value) {
console.log(key, value);
});
});
Output -
0 "Canada"
1 "Us"
2 "France"
3 "Italy"
We see above that we can loop a numerical array using the jQuery.each function and access info outside of the loop using square brackets with numerical keys.
Simple Object (json)
$(document).ready(function(){
var person = {
name: "James",
occupation: "programmer",
height: {
feet: 6,
inches: 1
},
}
console.log("My name is "+person.name+" and I am a "+person.height.feet+" ft "+person.height.inches+" "+person.occupation);
$.each(person, function(key, value) {
console.log(key, value);
});
});
Output -
My name is James and I am a 6 ft 1 programmer
name James
occupation programmer
height Object {feet: 6, inches: 1}
In a language like php this would be considered a multidimensional array with key value pairs, or an array within an array. I'm assuming because you asked about how to loop through a key value array you would want to know how to get an object (key=>value array) like the person object above to have, let's say, more than one person.
Well, now that we know javascript arrays are used typically for numeric indexing and objects more flexibly for associative indexing, we will use them together to create an array of objects that we can loop through, like so -
JSON array (array of objects) -
$(document).ready(function(){
var people = [
{
name: "James",
occupation: "programmer",
height: {
feet: 6,
inches: 1
}
}, {
name: "Peter",
occupation: "designer",
height: {
feet: 4,
inches: 10
}
}, {
name: "Joshua",
occupation: "CEO",
height: {
feet: 5,
inches: 11
}
}
];
console.log("My name is "+people[2].name+" and I am a "+people[2].height.feet+" ft "+people[2].height.inches+" "+people[2].occupation+"\n");
$.each(people, function(key, person) {
console.log("My name is "+person.name+" and I am a "+person.height.feet+" ft "+person.height.inches+" "+person.occupation+"\n");
});
});
Output -
My name is Joshua and I am a 5 ft 11 CEO
My name is James and I am a 6 ft 1 programmer
My name is Peter and I am a 4 ft 10 designer
My name is Joshua and I am a 5 ft 11 CEO
Note that outside the loop I have to use the square bracket syntax with a numeric key because this is now an numerically indexed array of objects, and of course inside the loop the numeric key is implied.
Objects inside an array:
var cars = [
{ "id": 1, brand: "Ferrari" }
, { "id": 2, brand: "Lotus" }
, { "id": 3, brand: "Lamborghini" }
];
Simply do this
var key = "keyOne";
var obj = {};
obj[key] = someValue;
I know its late but it might be helpful for those that want other ways. Another way array key=>values can be stored is by using an array method called map(); (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) you can use arrow function too
var countries = ['Canada','Us','France','Italy'];
// Arrow Function
countries.map((value, key) => key+ ' : ' + value );
// Anonomous Function
countries.map(function(value, key){
return key + " : " + value;
});

Categories

Resources