Convert javascript object to array of individual objects - javascript

I have the following object:
{English: 4, Math: 5, CompSci: 6}
How can I convert it to an array of objects, like:
[{English: 4}, {Math: 5}, {CompSci: 6}]
Can't find the answer anywhere. Thanks!!

Use Array#forEach over Object.keys(YOUR_OBJECT)
var input = {
English: 4,
Math: 5,
CompSci: 6
};
var op = [];
Object.keys(input).forEach(function(key) {
var obj = {};
obj[key] = input[key];
op.push(obj); //push newly created object in `op`array
});
console.log(op);

With newer JS, you could take Object.entries and map single properties.
var object = { English: 4, Math: 5, CompSci: 6 },
array = Object.entries(object).map(([k, v]) => ({ [k]: v }));
console.log(array);

Just loop over each of the keys in the object.
var oldObject = {English: 4, Math: 5, CompSci: 6};
var newArray = [];
// Loop over each key in the object
for (var key in oldObject) {
// Create a temp object
var temp = {};
// Set the key of temp
temp[key] = oldObject[key]
// Push it to the array
newArray.push(temp);
}
console.log(newArray)

you can directly assign object by {} but you must use [] quote for key value if not that will not worked
var obj = {English: 4, Math: 5, CompSci: 6};
var n_obj = [];
for(var i in obj){
n_obj.push({[i]:obj[i]});
}
console.log(n_obj);

You can turn the object into an array of key-value pairs using Object.entries and then map this array to smaller object created using Object.fromEntries from each individual key-value pair (the key part here is the wrapping in another array before passing to fromEntries):
Object.entries(obj).map(e => Object.fromEntries([e]))
The reverse way is similar: We create a big object using Object.fromEntries, and we pass in an array of key-value pairs. This array is created by flat-mapping (i.e. eliminating on extra layer of arrays) the array of objects to an array of key-value pairs we get from calling Object.entries on each small object. The key here is the flat-mapping, without it we would get an array of arrays of key-value pairs because we added that extra layer in the other conversion to separate the properties.
Object.fromEntries(arr.flatMap(o => Object.entries(o)))

You can use JSON.stringify(), String.prototype.match() with RegExp /".*"\:.*(?=,|})/, String.prototype.split() with RegExp /,/, Array.prototype.join() with parameter "},{", JSON.parse()
var obj = {English: 4, Math: 5, CompSci: 6};
var res = JSON.parse("[{"
+ JSON.stringify(obj)
.match(/".*"\:.*(?=,|})/g)[0]
.split(/,/)
.join("},{")
+ "}]");
console.log(res);

Related

Can't push to array in JavaScript

I get an error when I run this code:
var array = [];
array.push(["one"]:[1,2,3]);
array.push(["two"]:[4,5,6]);
I want my array to look like this in the end:
{"one": [1,2,3], "two": [4,5,6]};
I don't know how to fix this error, I want to use push.
An associative array in JavaScript is an object, so you can't use array.push as that's not valid there. You'd just want: array["one"] = [1,2,3]
var array = {};
array.one = [123, 123];
array.two = [123, 123];
console.log(array)
output
{
one: [
123,
123
],
two: [
123,
123
]
}
You should be opting for something like below. Using push, you will not achieve your desired output.
let obj = {};
const item1 = {
["one"]: [1, 2, 3]
}
const item2 = {
["two"]: [4, 5, 6]
}
obj = {
...obj,
...item1,
...item2
}
The reason you got the error is because you are missing object wrapper notation in your push {}
array.push({["one"]:[1,2,3]});
array.push({["two"]:[4,5,6]});
but as said, this will not give the desired output: {"one": [1,2,3], "two": [4,5,6]};
You must first create the object, assign values into the object, then push it into the array. Refer to this post for more information.
push object into array
Javascript doesn't have Associative Arrays like other languages, but it have Objects, that is similar.
var object = {};
object.one = [1,2,3];
// or if the key name comes from a variable:
var key = "two";
object[key] = [4,5,6];
"one" is an object not an array. remove the parenthesis from there. See below code:
array.push({"one":[1,2,3]});
array.push({"two":[4,5,6]});

Grouping array of objects and doing a calculation to create a new common value

I'm using lodash to group my objects in my array.
var grouped = _.groupBy(this.tableData, function(obj) {
return obj.key
});
It's giving me an object with key value pairs.
{mykey1: [{obj1}, {obj2}], mykey2: [obj1]}
My question is how can I loop through the objects inside each key and do a calculation. for example if I have an attribute in my object, cost, I want to sum up all the cost inside each object in my key?
You can use a combination of _.mapValues and _.sumBy:
var summed = _.mapValues(grouped, function(v){
return _.sumBy(v, 'cost');
});
Live example below:
var tableData = [
{key:"obj1",cost:1},
{key:"obj1",cost:1},
{key:"obj1",cost:1},
{key:"obj2",cost:1},
{key:"obj2",cost:1}
]
var grouped = _.groupBy(tableData, function(obj) {
return obj.key
});
var summed = _.mapValues(grouped, function(v){
return _.sumBy(v, 'cost');
});
console.log(summed);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
You could do native javascript:
//let obj = {key1: [{cost: 1}, {cost: 2}], key2: [{cost: 3}]}; example input
Object.values(obj).reduce((sum, arr)=> sum + arr.reduce((subsum, element)=>subsum + element.cost, 0), 0);
Explain:
Object.values(obj) //-> [[{cost: 1}, {cost: 2}], [{cost: 3}]]
[1, 2, 3].reduce((sum, element)=> sum + element), 0) //-> reduce (converting a list of things into one)

Convert ES6 Iterable to Array

Say you have an array-like Javascript ES6 Iterable that you know in advance will be finite in length, what's the best way to convert that to a Javascript Array?
The reason for doing so is that many js libraries such as underscore and lodash only support Arrays, so if you wish to use any of their functions on an Iterable, it must first be converted to an Array.
In python you can just use the list() function. Is there an equivalent in ES6?
You can use Array.from or spread syntax (...).
Example:
const x = new Set([ 1, 2, 3, 4 ]);
const y = Array.from(x);
console.log(y); // = [ 1, 2, 3, 4 ]
const z = [ ...x ];
console.log(z); // = [ 1, 2, 3, 4 ]
Summary:
Array.from() function, it takes an iterable as in input and returns an array of the iterable.
Spread syntax: ... in combination with an array literal.
const map = new Map([[ 1, 'one' ],[ 2, 'two' ]]);
const newArr1 = [ ...map ]; // create an Array literal and use the spread syntax on it
const newArr2 = Array.from( map ); //
console.log(newArr1, newArr2);
Caveat when copying arrays:
Be cognizant of the fact that via these methods above only a shallow copy is created when we want to copy an array. An example will clarify the potential issue:
let arr = [1, 2, ['a', 'b']];
let newArr = [ ...arr ];
console.log(newArr);
arr[2][0] = 'change';
console.log(newArr);
Here because of the nested array the reference is copied and no new array is created. Therefore if we mutate the inner array of the old array, this change will be reflected in the new array (because they refer to the same array, the reference was copied).
Solution for caveat:
We can resolve the issue of having shallow copies by creating a deep clone of the array using JSON.parse(JSON.stringify(array)). For example:
let arr = [1, 2, ['a', 'b']]
let newArr = Array.from(arr);
let deepCloneArr = JSON.parse(JSON.stringify(arr));
arr[2][0] = 'change';
console.log(newArr, deepCloneArr)
You can use the Array.from method, which is being added in ES6, but only supports arrays and iterable objects like Maps and Sets (also coming in ES6). For regular objects, you can use Underscore's toArray method or lodash's toArray method, since both libraries actually have great support for objects, not just arrays. If you are already using underscore or lodash, then luckily they can handle the problem for you, alongside adding various functional concepts like map and reduce for your objects.
The following approach is tested for Maps:
const MyMap = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
const MyArray = [...MyMap].map(item => {
return {[item[0]]: item[1]}
});
console.info( MyArray ); //[{"a", 1}, {"b", 2}, {"c": 3}]
<Your_Array> = [].concat.apply([], Array.from( <Your_IterableIterator> ));
You could also do the following, but both approaches are certainly not recommendable (merely a proof-of-concept for completeness):
let arr = [];
for (let elem of gen(...)){
arr.push(elem);
}
Or "the hard way" using ES5 + generator function (Fiddle works in current Firefox):
var squares = function* (n) {
for (var i = 0; i < n; i++) {
yield i * i;
}
};
var arr = [];
var gen = squares(10);
var g;
while (true) {
g = gen.next();
if (g.done) {
break;
}
arr.push(g.value);
}

Add array values into map using javascript?

I have an array value as a with key:value pair. I wanted to map the same key array values as below format:
Expected Output: [abc: 1],[def:2,42,40]
Please find my code below:
var a = {"abc": 1, "def": 2, "def": 42, "def" : 40};
var array_keys = new Array();
var array_values = new Array();
for (var key in a) {
array_keys.push(key);
array_values.push(a[key]);
}
alert(array_keys);
alert(array_values);
It returns the values as
My output : [abc:def] [1,40]
Any help on this?
You can achieve something like what you want if you play around with your initial data structure:
Have an array of objects:
var a = [{abc: 1}, {def: 2}, {def: 42}, {def: 40}];
Set up a new object
var o = {};
And then loop over the data. For each object: if the key doesn't exist in o, the output object, add it and set its value to an array, otherwise just push the value of the object to the array.
for (var i = 0, l = a.length; i < l; i++) {
var key = Object.keys(a[i]);
if (!o[key]) { o[key] = []; }
o[key].push(a[i][key]);
}
And you end up with an object the values of which are arrays:
console.log(o); // {abc: [1], def: [2,42,40] }
Demo
var a = {"abc": 1, "def": 2, "def": 42, "def" : 40};
This is not possible. Object keys must be unique in javascript, so you can't add 3 different items with the same key ("def"). If you define multiple elements with the same key, at least chrome will take the last added value.
So answering your question: With the input provided there is no way to get you Expected output.

Get the key of an associative array

I'm currently fetching an array with .each:
$.each(messages, function(key,message){ doStuff(); });
But the key is the index of the array and not the associative key.
How can I get it easily?
JavaScript doesn't have "associative arrays". It has arrays:
[1, 2, 3, 4, 5]
And objects:
{a: 1, b: 2, c: 3, d: 4, e: 5}
Array's don't have "keys". They have indices, which are counted starting at 0.
Arrays are accessed using [], and objects can be accessed using [] or ..
Example:
var array = [1,2,3];
array[1] = 4;
console.log(array); // [1,4,3]
var obj = {};
obj.test = 16;
obj['123'] = 24;
console.log(obj); // {test: 16, 123: 24}
If you try to access an array using a string as a key instead of an int, that may cause problems. You would be setting a property of the array and not a value.
var array = [1,2,3];
array['test'] = 4; // This doesn't set a value in the array
console.log(array); // [1,2,3]
console.log(array.test); // 4
jQuery's $.each works with both of these. In the callback for $.each, the first parameter, key, is either the object's key, or the array's index.
$.each([1, 2, 3, 4, 5], function(key, value){
console.log(key); // Logs 0 1 2 3 4
});
$.each({a: 1, b: 2, c: 3, d: 4, e: 5}, function(key, value){
console.log(key); // Logs 'a' 'b' 'c' 'd' 'e'
});
var data = {
val1 : 'text1',
val2 : 'text2',
val3 : 'text3'
};
$.each(data, function(key, value) {
alert( "The key is '" + key + "' and the value is '" + value + "'" );
});
​
See the Demo
JavaScript doesn't have "associative arrays" as in PHP, but objects. Objects, though, may have string keys that corresponds to a value. Arrays are lists of values indexed numerically, so, if key is a number, it must be an array you are working with and not an object, and therefore you cannot get the key, as there is none.
Thus, you'd probably want to iterate over an array with a simple for-loop instead of a callback-based iterator such as $.each.

Categories