How to convert a hash to a single object in JavaScript? - javascript

I am having an array of object in the below format:
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
}];
which I want to convert in a single object like:
var log={
"Name":"ABC",
"Department":"Computer"
};
I've tried the following approach:
for(var i=0;i<log.length;++i){
pushToAry(log[i].billkey, log[i].billvalue);
}
function pushToAry(name, val) {
var obj = {};
obj[name] = val;
ary.push(obj);
}
But it will push a new object every time into the ary array, which results into:
var ary =[
0:{
"Name":"ABC"
},
1:{
"Department":"Computer"
}];
How could I convert this array of object into an object?

In ES6 this is quite clean:
let result = {};
for (let {billkey, billvalue} of log)
result[billkey] = billvalue;
or if you prefer "functional" style:
let result = Object.assign(...log.map(x => ( {[x.billkey]: x.billvalue} )))

You can use reduce() to return object.
var log = [{
billkey: "Name",
billvalue: "ABC"
}, {
billkey: "Department",
billvalue: "Computer"
}];
var result = log.reduce((r, e) => (r[e.billkey] = e.billvalue, r), {});
console.log(result)

If you just want to use a loop, you can do it like this :
var log = [
{
billkey: "Name",
billvalue: "ABC"
},
{
billkey: "Department",
billvalue: "Computer"
}];
var result = {};
log.forEach(x => result[x.billkey] = x.billvalue);
console.log(result);

You can use Array.prototype.reduce to reduce it to the required object - see demo below:
var log=[{billkey:"Name",billvalue:"ABC"},{ billkey:"Department",billvalue:"Computer"}];
var result = log.reduce(function(p,c){
p[c.billkey] = c.billvalue;
return p;
},{})
console.log(result);

var obj = {};
for (var i = 0; i < log.length; i++)
obj[log[i].billkey] = log[i].billvalue;
First, I prepare an empty object to store reult to. Then I go through the log and in every iteration, I extract the log record's key (log[i].billkey) and value (log[i].billvalue) and use it to add the new member to the result: obj[...key...] = ...value...;.

Related

How can I convert an array of strings to an array of objects in JavaScript?

I have this array:
myArray = ["AAA","BBB",...,"ZZZ"];
I want to convert it to an array of objects. Something like this:
myArray = [
{
"Id": "111",
"Value": "AAA"
},
....
{
"Id": "111",
"Value": "ZZZ"
},
];
I've tried to use the map method like this:
myArray.map(str => {
let obj = {};
obj['Id'] = '111';
obj['Value'] = str;
});
But console.log(myArray) outputs this:
undefined
You need to return a result from the mapper function.
let myNewArray = myArray.map( str => {
let obj = {};
obj['Id'] = '111' ;
obj['Value'] = str ;
return obj;
});
// or
let myNewArray = myArray.map( str => ({Id:111,Value:str}) );
// parenthesis are needed to remove the ambiguity with `{}`
console.log(myNewArray);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Using_map_to_reformat_objects_in_an_array
Here is the clean ES6 one liner version using Array#map
const data = myArray = ["AAA","BBB","ZZZ"];
let result = data.map(e => ({'Id': '111', 'Value': e}));
console.log(result);
You need to return the result into a new variable, or your existing one, as map create a new array and doesn't change the one you are iterating over.
const myArrayOfObjects = myArray.map( str => {
let obj = {};
obj['Id'] = '111' ;
obj['Value'] = str ;
return obj;
});

CSV data loading as array of arrays; How to convert into object?

I was wanting to see if there is a relatively simple method for doing this as I can use the following:
var arr = [ "Client", "ActType", "CallRepType"];
var arr2 = [ "ECF", "Meeting", "Call Report"]
var myobj = arr2.map(value => ({'Client': arr2[0], 'ActType': arr2[1], 'CallRepType': arr2[2]}));
But I get the same correct object 3 times in a row...I simply want a single object returned that looks like:
{Client: 'ECF', ActType: 'Meeting', CallRepType: 'Call Report'}
I know I can loop through both arrays but I was hoping to get a solution using map, reduce or taking advantage of spread in javascript...
A faster solution that uses Array.prototype.forEach():
var arr = [ "Client", "ActType", "CallRepType"];
var arr2 = [ "ECF", "Meeting", "Call Report"]
var result = {};
arr.forEach((el, i) => { result[el] = arr2[i]; });
console.log(result);
Array.prototype.forEach()`
This a solution that uses Array.reduce() to create the object:
const arr = [ "Client", "ActType", "CallRepType"];
const arr2 = [ "ECF", "Meeting", "Call Report"]
const myobj = arr.reduce((r, key, i) => {
r[key] = arr2[i];
return r;
}, {});
console.log(myobj);
You can loop through the array and do it:
var arr = [ "Client", "ActType", "CallRepType"];
var arr2 = [ "ECF", "Meeting", "Call Report"];
var len = arr.length;
var myObj = {};
for (var i = 0; i < len; i++) {
var myObject = {};
myObj[arr[i]] = arr2[i]
// myObj.push = myObject;
}
console.log(myObj);

filter unique properties from array of objects with unique values if existing then override the value

I am trying to iterate array of objects with different properties. where I am adding objects dynamically and want to check whether the property of the object is exist in the array then only override the value else add it to the array.
For e.x.
var arr = [
{"value":"abc"},
{"type":"def"},
{"status":"ghi"},
{"value":"xyz"}
]
expected result:
arr = [
{"value":"xyz"},
{"type":"def"},
{"status":"ghi"}
]
What I am trying so far is not working. Here is my code:
var arr = [
{"value":"abc"},
{"type":"def"},
{"status":"ghi"},
{"value":"abc"}
]
var obj={};
var key1 = "type", value="xyz";
obj[key1] = value;
var newarr = arr.filter(function(entry,i) {
if (!entry.hasOwnProperty(key1)) {
return true;
}
});
newarr.push(obj);
Please note, the obj will be dynamic so my code is working fine for first time when the property of key1 doesn't change. once I change the value of key1 from "type" to "status", It is adding objects 2 times.
Can anybody help me around this?
Try this Array.reduce() function and Object.keys() method.
array#reduce() used to recreate with new array
Object.keys() get the key of the each object .Array#map() create the array of all object keys .
Then match if not includes in the array then push with new array
Updated replace the type with new one value
var arr = [{"value":"abc"}, {"type":"def"}, {"status":"ghi"}, {"value":"xyz"}];
var key1 = "type";
var value="xyz";
var result = arr.reduce((a,b) =>{
if(!a.map(i=> Object.keys(i)[0]).includes(Object.keys(b)[0]))
{
if(b.hasOwnProperty(key1)){
b[key1]=value
}
a.push(b)
}
return a}, []);
console.log(result);
The following code should do the job:
var arr = [
{"value":"abc"},
{"type":"def"},
{"status":"ghi"},
{"value":"xyz"}
];
var obj = {};
for (i in arr) {
key = Object.keys(arr[i])[0];
obj[key] = arr[i][key];
}
console.log(obj);
The solution using ES6 Array.prototype.reduce() and Object.assign() functions:
var arr = [{"value":"abc"}, {"type":"def"}, {"status":"ghi"}, {"value":"xyz"}],
obj = arr.reduce((r,o) => Object.assign(r,o), {}),
result = Object.keys(obj).map( (k) => { o = {}; o[k]=obj[k]; return o } );
console.log(result);
You could use a hash table and filter and update all found same key objects.
var array = [{ value: "abc" }, { type: "def" }, { status: "ghi" }, { value: "ddd" }],
key = "type",
value = "xyz",
update = false,
hash = Object.create(null),
temp = {};
temp[key] = value;
array.push(temp);
array = array.filter(function (o) {
var key = Object.keys(o)[0];
if (!hash[key]) {
hash[key] = o;
return true;
}
hash[key][key] = o[key];
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

create a grouped array using two different arrays

I have below two arrays:
array1 = [{
"type":"test",
"name":"name1"},
{
"type":"dev",
"name":"name2"}]
array2=[{
"type":"test",
"name":"name3"},
{
"type":"dev",
"name":"name4"},
{
"type":"prod",
"name":"name5"}]
I want to group two arrays with "type" and create a new array something like this:
finalArray=[{
"type":"test",
"info":[{
"type":"test",
"name":"name1"}],
[{
"type":"test",
"name":"name3"
}]},
{
"type":"dev",
"info":[{
"type":"dev",
"name":"name2"}],
[{
"type":"dev",
"name":"name4"}]},
{
"type":"prod",
"info":[],
[{
"type":"prod",
"name":"name5"}]
}]
Is there anyway that I can achieve this using javascript, angularjs2, lodash, jquery. I am able to group and create new object as mentioned in using lodash .groupBy. how to add your own keys for grouped output?
But only thing is always I want to push the data from second array in index=1 of "info" and first one to index=0. If any of the array does not have a "type" then the "info" array should have empty/null values.
use _.mapValues to iterate object values with key accessing
var res = _.chain(array1)
.concat(array2)
.groupBy('type')
.mapValues(function(val, key) {
return {
type: key,
info: val
};
})
.values()
.value();
It's possible to achieve the result you want in javascript, or using helper like lodash.
The last part of your question is hard to understand. If an array doesn't have "type", how would you group them. Please provide clearer explanation or modify your expected input and output.
[Updated]
Thanks for your explanation. This is the solution using plain javascript.
// get uniques type from two arrays
const uniqueTypes = new Set(array1
.concat(array2)
.map(x => x.type));
// loop the types, find item in both array
// group it
let result = Array.from(uniqueTypes).reduce((acc, curr) => {
const item1 = array1.find(x => x.type === curr);
const item2 = array2.find(x => x.type === curr);
const info1 = item1 ? [item1] : [];
const info2 = item2 ? [item2] : [];
acc = acc.concat({ type: curr, info: [info1, info2] });
return acc;
}, []);
console.log(result);
jsbin here: https://jsbin.com/mobezogaso/edit?js,console
Here's a working solution :). Hope it helps!
var array1 = [
{
"type":"test",
"name":"name1"
},
{
"type":"dev",
"name":"name2"
}
]
var array2 = [
{
"type":"test",
"name":"name3"
},
{
"type":"dev",
"name":"name4"
},
{
"type":"prod",
"name":"name5"
}
]
var newArray = array1.concat(array2);
var arr1 = [];
var arr2 = [];
var arr3 = [];
var arrTypes = [];
var finalArray = [];
var someArray = [];
for(var i in newArray)
{
if (arrTypes.indexOf(newArray[i].type) === -1){
arrTypes.push(newArray[i].type);
}
if(newArray[i].type === "test"){
arr1.push(newArray[i]);
}
else if(newArray[i].type === "dev"){
arr2.push(newArray[i]);
}
else if(newArray[i].type === "prod"){
arr3.push(newArray[i]);
}
}
someArray.push(arr1);
someArray.push(arr2);
someArray.push(arr3);
for(var j = 0; j < someArray.length; j++){
finalArray.push({
"type": arrTypes[j],
"info": someArray[j]
});
}
console.log(finalArray);
And a short (unreadable?) ES6 solution:
Concat the arrays
Reduce the array into a Map object, with the type as the key
Get the entries iterator - key (type) - value (array of objects)
Use spread to convert the entry iterator to an array
Array#Map the array of entries to the type/info objects
const array1 = [{"type":"test","name":"name1"},{"type":"dev","name":"name2"}];
const array2=[{"type":"test","name":"name3"},{"type":"dev","name":"name4"},{"type":"prod","name":"name5"}];
const result = [...array1.concat(array2).reduce((r, o) => {
r.has(o.type) ? r.get(o.type).push(o) : r.set(o.type, [o]);
return r;
}, new Map).entries()]
.map(([type, info]) => ({
type, info
}));
console.log(result);

How to convert array of key–value objects to array of objects with a single property?

I have an array of objects like this:
[
{ "key": "fruit", "value": "apple" },
{ "key": "color", "value": "red" },
{ "key": "location", "value": "garden" }
]
I need to convert it to the following format:
[
{ "fruit": "apple" },
{ "color": "red" },
{ "location": "garden" }
]
How can this be done using JavaScript?
You can use .map
var data = [
{"key":"fruit","value":"apple"},
{"key":"color","value":"red"},
{"key":"location","value":"garden"}
];
var result = data.map(function (e) {
var element = {};
element[e.key] = e.value;
return element;
});
console.log(result);
also if you use ES2015 you can do it like this
var result = data.map((e) => {
return {[e.key]: e.value};
});
Example
Using an arrow function, with the data called arr
arr.map(e => {
var o = {};
o[e.key] = e.value;
return o;
});
This generates a new Array and does not modify the original
It can be simplified down to one line as
arr.map(e => ({[e.key]: e.value}));
If you can't assume arrow function support yet, you would write this longhand
arr.map(function (e) {
var o = {};
o[e.key] = e.value;
return o;
});
Using map (as suggested in other answers) or the following will do what you want...
var data = [{"key":"fruit","value":"apple"},{"key":"color","value":"red"},{"key":"location","value":"garden"}];
var obj = {};
for(var i = 0; i < data.length; i++) {
obj[data[i]["key"]] = data[i]["value"];
}
In Javascript, obj.property and obj['property'] return same things.
obj['property'] is more flexible because the key 'property' could be a string with some space :
obj['pro per ty'] // work
obj.pro per ty // not work
or
var a = 'property';
obj.a == obj.property // => false
obj[a] == obj.property // => true
So you could try that.
var data = [{"key":"fruit","value":"apple"},{"key":"color","value":"red"},{"key":"location","value":"garden"}]
var new_data = [];
var data_length = data.length; // just a little optimisation for-loop
for (var i = 0; i < data_length; i++) {
var item = data[i]; // to have a vision close of foreach-loop (foreach item of collection)
new_data[i] = {};
new_data[i][item.key] = item.value;
}
console.log(new_data);
// [{"fruit":"apple"},{"color":"red"},{"location":"garden"}]
What you currently have is an array of object, each having two attributes, key and value. If you are not aware of map, you can always run a forEach loop on this array and rearrange the data. Try something like below:
function() {
var newArray = [];
oldArray.forEach(function(x){
var obj= {};
obj[x.key] = x.value;
newArray.push(obj);
});
console.log(newArray);
}
here oldArray is your original data

Categories