This is how an API reponse looks like.
{
"keys": ["CustomerId", "Name", "Gender"],
"value": [["1", "Ram", "Male"]]
}
Angular VM
function Customer(){
return this.Customer = {
"CustId": "",
"Name": "",
"Gender": "",
}
}
Angular AJAX Call.
$http.get(url)
.then(function(data)){
var cust = new Customer();
//for now I am doing this way.
cust.Id = data.value[0][0];
cust.Name = data.value[0][1];
cust.Gender = data.value[0][1];
}
I don't want to map the properties by index.
These APIs not into my control
Is there any way, where I can map the properties by key (in response) as below.
cust.Id = data.value[0]["CustomerId"];
cust.Name = data.value[0]["Name"];
cust.Gender = data.value[0]["Gender"];
Any help/suggestion highly appreciated.
The only way I can see of achieving something like this is by finding the index of each key and using that as the index when accessing your values like this:
$http.get(url)
.then(function(data){
var cust = new Customer();
cust.Id = data.value[0][data.keys.indexOf('CustomerId')];
cust.Name = data.value[0][data.keys.indexOf('Name')];
cust.Gender = data.value[0][data.keys.indexOf('Gender')];
});
But note, this will only work if the keys and values match up ... which I assume they will.
If you are able to use ES6, the best workaround (for this poorly made API) would be to create a parser function like that:
function parseResponse(response) {
const {keys, value: objects} = response;
return objects.map(object => {
const parsedValue = {};
keys.forEach((key, index) => {
parsedValue[key] = object[index];
});
return parsedValue;
});
}
Tests:
const response = {
"keys": ["CustomerId", "Name", "Gender"],
"value": [["1", "Ram", "Male"]]
};
parseResponse(response); // Outputs [{CustomerId: "1", Name: "Ram", Gender: "Male"}]
If you wish, I could make that with ES5. Just say the word :)
EDIT
ES5 Version:
function parseResponse(response) {
var keys = response.keys;
var objects = response.value;
var response = [];
for (let i = 0; i < objects.length; i++) {
var formattedValue = {};
for (let j = 0; j < keys.length; j++) {
var key = keys[j];
formattedValue[key] = objects[i][j];
}
response.push(formattedValue);
}
return response;
}
Related
I'm having trouble wrapping my mind around javascript hashmaps and JSON arrays. I'm trying to count duplicate import countries from a JSON array. For instance the data is:
[
{
"id": 1,
"import_country": "Russia",
"model": "Express 2500",
"make": "Chevrolet",
"sold_by": "Sibylla Kneale",
"sale_price": 14702
},
{
"id": 2,
"import_country": "Philippines",
"model": "G-Class",
"make": "Mercedes-Benz",
"sold_by": "Gabie Gradwell",
"sale_price": 19142
},
{
"id": 3,
"import_country": "Russia",
"model": "M",
"make": "Infiniti",
"sold_by": "Burl Pitkeathley",
"sale_price": 18395
}
]
This is what I have for code so far:
var country = [];
var temp = [];
const model = [];
const count = 0;
const response = await fetch('some api url where data is retrieved')
.then(response => response.json())
.then(data => {
var key = {};
for(i = 0; i< data.length; i++){
if(temp.indexOf(data[i].import_country) == -1){
temp.push(data[i][import_country]);
var _data = {};
}
}
});
My end goal is to have the total country count displayed on a graph.
A good way to do this would be to use a hashmap instead of arrays like you said.
If we update your code to be this:
var hashmap = {};
const response = await fetch('some api url where data is retrieved')
.then(response => response.json())
.then(data => {
var key = {};
for(i = 0; i< data.length; i++){
let country = data[i]['import_country'];
if (hashmap[country] == void(0)) { // if it doesn't exist in the hashmap
hashmap[country] = []; // create it in the map
}
hashmap[country].push(data[i]); // add it to the country array in the temp
}
})
If the data you are receiving above is correct, the output would look something like this:
{
"Russia": [
{"id":1,"import_country":"Russia","model":"Express 2500","make":"Chevrolet","sold_by":"Sibylla Kneale","sale_price":14702},
{"id":3,"import_country":"Russia","model":"M","make":"Infiniti","sold_by":"Burl Pitkeathley","sale_price":18395}
],
"Phillipines": [
{"id":2,"import_country":"Philippines","model":"G-Class","make":"Mercedes-Benz","sold_by":"Gabie Gradwell","sale_price":19142}
]
}
Now that we have the data formatted how we would like, we can loop through it to get the total country count:
... // code from above
for (var country in map) {
console.log(country + ": " + country.length + " cars");
}
That code would output:
Russia: 2 cars
Phillipines: 1 cars
Try below code -
var jsonArray = [{"id":1,"import_country":"Russia","model":"Express 2500","make":"Chevrolet","sold_by":"Sibylla Kneale","sale_price":14702},{"id":2,"import_country":"Philippines","model":"G-Class","make":"Mercedes-Benz","sold_by":"Gabie Gradwell","sale_price":19142},{"id":3,"import_country":"Russia","model":"M","make":"Infiniti","sold_by":"Burl Pitkeathley","sale_price":18395}];
var map = new Map();
for(var i=0;i<jsonArray.length;i++){
if(!map.get(jsonArray[i].import_country)){
map.set(jsonArray[i].import_country,1);
}else{
map.set(jsonArray[i].import_country, map.get(jsonArray[i].import_country) + 1);
}
}
Pseudo Code:-
Getting a JSON array.
Creating an empty map.
for i=0 to JSON Array length.
a. if the map doesn't contain the country, then set the country with count 1.
b. else set already existing key in the map by increasing with count 1.
End.
I am trying to convert an object literal into an array of arrays by using a function.
Using the two sample objects I have, the end result I'm looking for would be:
[ ["ugh","grr"] , ["foo", "bar"] , ["blah" , 138] ] from obj1
[ "shambala","walawala"] , ["foofighter","Barstool"] , ["blahblah",1382342453] ] from obj2
var obj1 = {
ugh: "grr",
foo: "Bar",
blah: 138
};
var obj2 = {
shambala: "walawala",
foofighter: "Barstool",
blahblah: 1382342453
};
var piece1 = Object.keys(obj1);
var piece2 = Object.values(obj1);
var result = [ ];
for (var i = 0; i < piece1.length; i++) {
result.push([piece1[i] , piece2[i]])
}
console.log(result)
From what I have above, I have been able to achieve:
[ ["ugh","grr"] , ["foo", "bar"] , ["blah" , 138] ] from obj1
But I am stumped about how to achieve the same output via a function.
This seems like a simple thing.
function objToArray(objectLiteral) {
var piece1 = Object.keys(objectLiteral);
var piece2 = Object.values(objectLiteral);
var result = [ ];
for (var i = 0; i < piece1.length; i++) {
return result.push([piece1[i] , piece2[i]])
}
}
console.log(objToArray(obj1))
This is what the best I can do but I keep on getting 1 and I don't know why.
Other attempts I just end up with undefined.
The problem with your code is you're using the return earlier than needed, see this working code:
var obj1 = {
ugh: "grr",
foo: "Bar",
blah: 138
};
var obj2 = {
shambala: "walawala",
foofighter: "Barstool",
blahblah: 1382342453
};
function objToArray(objectLiteral) {
var piece1 = Object.keys(objectLiteral);
var piece2 = Object.values(objectLiteral);
var result = [];
for (var i = 0; i < piece1.length; i++) {
result.push([piece1[i], piece2[i]])
}
return result;
}
console.log(objToArray(obj1));
If it's supported in your environment, you could use Object.entries:
var obj1 = {
ugh: "grr",
foo: "Bar",
blah: 138
};
var pairs = Object.entries(obj1);
Alternatively, you could write an entries function like this:
function entries(object) {
const pairs = [];
for(let key in object) {
if(object.hasOwnProperty(key)) {
pairs.push([key, object[key]]);
}
}
return pairs;
}
Here's how I'd implement it.
function objectToArray(obj) {
return Object.keys(obj).map(function(prop) {
return [prop, obj[prop]];
});
}
// ES2015
function objectToArray (obj) {
return Object.keys(obj).map(prop => [prop, obj[prop]]);
}
View demo
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
I'm loading an external JSON file into javascript, the JSON file looks like this:
[
{
"name":"Apple",
"year":8,
"records_lost":12367232
},
{
"name":"178.com",
"year":7,
"records_lost":10000000
},
{
"name":"Accendo Insurance Co. ",
"year":7,
"records_lost":175350
}
]
Eventually, I want to access the data via a Javascript object like this (don't mind the syntax). The point is that name will be a parent with its own meta-data.
"Apple":
"year":8,
"records_lost":12367232
"178.com":
"year":7,
"records_lost":10000000
This is the code I've already written for this part, which doesn't make name parent yet and only saves the last row of the JSON file into the array (+= instead of = would fix this, but delivers ugly values, obviously).
function initJSON() {
loadJSON(function(response) {
var JSONParse = JSON.parse(response);
var i;
for (i in JSONParse) {
JSONdata.name.i = JSONParse[i].name;
JSONdata.year = JSONParse[i].year;
JSONdata.recl = JSONParse[i].records_lost;
}
});
}
initJSON();
Thanks in forward.
Try utilizing Array.prototype.map() , delete operator
var data = [{
"name": "Apple",
"year": 8,
"records_lost": 12367232
}, {
"name": "178.com",
"year": 7,
"records_lost": 10000000
}, {
"name": "Accendo Insurance Co. ",
"year": 7,
"records_lost": 175350
}];
var res = data.map(function(val, key) {
var obj = {};
obj[val.name] = val;
delete obj[val.name].name;
return obj
});
document.getElementsByTagName("pre")[0].textContent = JSON.stringify(res, null, 4);
<pre></pre>
it should be :
var i;
for (i in JSONParse) {
JSONdata.name = i.name;
JSONdata.year = i.year;
JSONdata.recl = i.records_lost;
}
unless your loop was different:
var i;
for (i = 0; i < JSONParse.length; i++) {
JSONdata.name = JSONParse[i].name;
JSONdata.year = JSONParse[i].year;
JSONdata.recl = JSONParse[i].records_lost;
}
I have an array of objects as follows within my server side JS:
[
{
"Company": "IBM"
},
{
"Person": "ACORD LOMA"
},
{
"Company": "IBM"
},
{
"Company": "MSFT"
},
{
"Place": "New York"
}
]
I need to iterate through this structure, detect any duplicates and then create a count of a duplicate is found along side each value.
Both of the values must match to qualify as a duplicate e.g. "Company": "IBM" is not a match for "Company": "MSFT".
I have the options of changing the inbound array of objects if needed. I would like the output to be an object, but am really struggling to get this to work.
EDIT: Here is the code I have so far where processArray is the array as listed above.
var returnObj = {};
for(var x=0; x < processArray.length; x++){
//Check if we already have the array item as a key in the return obj
returnObj[processArray[x]] = returnObj[processArray[x]] || processArray[x].toString();
// Setup the count field
returnObj[processArray[x]].count = returnObj[processArray[x]].count || 1;
// Increment the count
returnObj[processArray[x]].count = returnObj[processArray[x]].count + 1;
}
console.log('====================' + JSON.stringify(returnObj));
For example:
counter = {}
yourArray.forEach(function(obj) {
var key = JSON.stringify(obj)
counter[key] = (counter[key] || 0) + 1
})
Docs: Array.forEach, JSON.stringify.
Object.prototype.equals = function(o){
for(var key in o)
if(o.hasOwnProperty(key) && this.hasOwnProperty(key))
if(this[key] != o[key])
return false;
return true;
}
var array = [/*initial array*/],
newArray = [],
ok = true;
for(var i=0,l=array.length-1;i<l;i++)
for(var j=i;j<l+1;j++)
{
if(!array[i].equals(array[j]))
newArray.push(array[i]);
}
We are required to write a JavaScript function that takes in one such array of objects. The function creates and return a new array in which no objects are repeated (by repeated we mean objects having same value for "Country" property.)
Moreover, the function should assign a count property to each object that represents the number of times they appeared in the original array.
const arr = [
{
"Country": "BR",
"New Lv1−Lv2": "#N/A"
},
{
"Country": "BR",
"New Lv1−Lv2": "#N/A"
},
{
"Country": "",
"New Lv1−Lv2": "test"
}];
const convert = (arr) => {
const res = {};
arr.forEach((obj) => {
const key = `${obj.Country}${obj["New Lv1−Lv2"]}`;
if (!res[key]) {
res[key] = { ...obj, count: 0 };
};
res[key].count += 1;
});
return Object.values(res);
};
console.log(convert(arr));
know more
With ES6, one can use Array#reduce with an object to store the counts.
let counts = arr.reduce((acc, curr)=>{
const str = JSON.stringify(curr);
acc[str] = (acc[str] || 0) + 1;
return acc;
}, {});
Demo
To create a new array without duplicates, a Set can be used with Array#filter.
let set = new Set;
let res = arr.filter(x => {
const str = JSON.stringify(x);
return !set.has(str) && set.add(str);
});
Demo