JS use a single string as key for multidimensional array - javascript

Let's say I have this variable:
var myvar = {
welcome: "Welcome!",
thx: "Thank you!",
...
}
Then, I have a function, which gets sent a string and return the value from that variable:
function myFunction(key){
return myvar[key]
}
So this happens:
console.log(myFunction('welcome')) ///prints Welcome!
That's all great, and works beautifully, but what if then I wanna add something like months to the original variable, and I want something like this
var myvar={
.
.
months: [
["jan", "January"],
..
}
So if I wanna call for example, January, I'd do
myvar[months][0][1] //Select the months part, 0 means it's january, 1 means its fully written not just "jan"
I could, for example, in my key do something like months-0-1 and split it to get all 3 keys; but how could I adapt my original function to work for both the original content (welcome, thx) and for the months?
Second part to this question, should I even do it or would it be a not very optimal solution, should I just go with the whole adding each entry into the variable like before method?
Note: I still want the answer to my first question, if nothing else because I want to know how it could be done, even if I don't end up doing it.
A bit more information of the use case, I have a data-translate tag on some objects in my html, and some that are generated dynamically, these variables are for language translation, and they all call that function either when they are made or when the language changes. (data-translate="welcome") for example

You can update your function code to be like below and pass keys as - separated values as you have mentioned. Refer this article Array.prototype.reduce() if you are not familiar with it.
return key.split('-').reduce((a, i) => a[i], myvar);
Try it below.
var myvar = {
welcome: "Welcome!",
thx: "Thank you!",
months: [
["jan", "January"]
]
};
function myFunction(key) {
return key.split('-').reduce((a, i) => a[i], myvar);
}
console.log(myFunction('welcome')); // prints Welcome!
console.log(myFunction('months-0-1')); // prints January!

We can do something like this
var myvar = {
welcome: "Welcome!",
thx: "Thank you!",
months: [
["jan", "January"]]
};
function myFunction(key){
let keys = key.split("-");
let len = keys.length;
let result = myvar, i=0;
while(i < len)
result = result[keys[i++]];
return result;
};
console.log(myFunction("welcome"), myFunction("months-0-0"))

Related

Function returning object instead of Array, unable to .Map

I'm parsing an order feed to identify duplicate items bought and group them with a quantity for upload. However, when I try to map the resulting array, it's showing [object Object], which makes me think something's converting the return into an object rather than an array.
The function is as follows:
function compressedOrder (original) {
var compressed = [];
// make a copy of the input array
// first loop goes over every element
for (var i = 0; i < original.length; i++) {
var myCount = 1;
var a = new Object();
// loop over every element in the copy and see if it's the same
for (var w = i+1; w < original.length; w++) {
if (original[w] && original[i]) {
if (original[i].sku == original[w].sku) {
// increase amount of times duplicate is found
myCount++;
delete original[w];
}
}
}
if (original[i]) {
a.sku = original[i].sku;
a.price = original[i].price;
a.qtty = myCount;
compressed.push(a);
}
}
return compressed;
}
And the JS code calling that function is:
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
The result is:
contents: [ [Object], [Object], [Object], [Object] ]
When I JSON.stringify() the output, I can see that it's pulling the correct info from the function, but I can't figure out how to get the calling function to pull it as an array that can then be mapped rather than as an object.
The correct output, which sits within a much larger feed that gets uploaded, should look like this:
contents:
[{"id":"sku1","price":17.50,"quantity":2},{"id":"sku2","price":27.30,"quantity":3}]
{It's probably something dead simple and obvious, but I've been breaking my head over this (much larger) programme till 4am this morning, so my head's probably not in the right place}
Turns out the code was correct all along, but I was running into a limitation of the console itself. I was able to verify this by simply working with the hard-coded values, and then querying the nested array separately.
Thanks anyway for your help and input everyone.
contents: compressedOrder(item.lineItems).map(indiv => ({
"id": indiv.sku,
"price": indiv.price,
"quantity": indiv.qtty
}))
In the code above the compressedOrder fucntion returns an array of objects where each object has sku, price and qtty attribute.
Further you are using a map on this array and returning an object again which has attributes id, price and quantity.
What do you expect from this.
Not sure what exactly solution you need but I've read your question and the comments, It looks like you need array of arrays as response.
So If I've understood your requirement correctly and you could use lodash then following piece of code might help you:
const _ = require('lodash');
const resp = [{key1:"value1"}, {key2:"value2"}].map(t => _.pairs(t));
console.log(resp);
P.S. It is assumed that compressedOrder response looks like array of objects.

How to convert arrays to objects in javascript?

How could I rewrite this code to object javascript. Since Array usage is prohibed, I can only use objects here. Insted of pushing values to array, I would like to push this values into objects.
var container = [];
document.addEventListener("submit", function(e){
e.preventDefault();
});
window.addEventListener("load",function(){
var submit = document.getElementsByClassName("btn-primary");
submit[0].addEventListener("click",add,false);
document.getElementById("pobrisi").addEventListener("click",deleteAll,false);
var dateElement = document.getElementById('datum');
dateElement.valueAsDate = new Date();
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1;
var yyyy = today.getFullYear();
if(dd<10){
dd='0'+dd
}
if(mm<10){
mm='0'+mm
}
today = yyyy+'-'+mm+'-'+dd;
dateElement.setAttribute("min",today);
});
function add() {
var title = document.getElementById("title").value;
var type = document.getElementById("type").value;
var datum = document.getElementById("datum").value.split("-");
datum = datum[2]+". "+datum[1]+". "+datum[0];
var data = new Book(title,type,datum);
container.push(data.add());
display();
}
function display(data) {
var destination = document.getElementById("list");
var html = "";
for(var i =0;i <container.length; i++) {
html +="<li>"+container[i]+"</li>";
}
destination.innerHTML = html;
}
function deleteAll(){
container=[];
document.getElementById("list").innerHTML="";
}
Wondering if is possible to write this code whitout any array usage.
initial remarks
The problem here, in my estimation, is that you haven't learned the fundamentals of data abstraction yet. If you don't know how to implement an array, you probably shouldn't be depending on one quite yet. Objects and Arrays are so widespread because they're so commonly useful. However, if you don't know what a specific data type is affording you (ie, what convenience does it provide?), then it's probable you will be misusing the type
If you take the code here but techniques like this weren't covered in your class, it will be obvious that you received help from an outside source. Assuming the teacher has a curriculum organized in a sane fashion, you should be able to solve problems based on the material you've already covered.
Based on your code, it's evident you really have tried much, but why do you think that people here will come up with an answer that your teacher will accept? How are we supposed to know what you can use?
a fun exercise nonetheless
OK, so (we think) we need an Array, but let's pretend Arrays don't exist. If we could get this code working below, we might not exactly have an Array, but we'd have something that works like an array.
Most importantly, if we could get this code working below, we'd know what it takes to make a data type that can hold a dynamic number of values. Only then can we begin to truly appreciate what Array is doing for us.
// make a list
let l = list(1) // (1)
// push an item on the end
l = push(l, 2) // (1 2)
// push another item on the end
l = push(l, 3) // (1 2 3)
// display each item of the list
listeach(l, function (x) {
console.log(x)
})
// should output
// 1
// 2
// 3
runnable demo
All we have to do is make that bit of code (above) work without using any arrays. I'll restrict myself even further and only use functions, if/else, and equality test ===. I see these things in your code, so I'm assuming it's OK for me to use them too.
But am I supposed to believe your teacher would let you write code like this? It works, of course, but I don't think it brings you any closer to your answer
var empty = function () {}
function isEmpty (x) {
return x === empty
}
function pair (x,y) {
return function (p) {
return p(x,y)
}
}
function head (p) {
return p(function (x,y) {
return x
})
}
function tail (p) {
return p(function (x,y) {
return y
})
}
function push (l, x) {
if (isEmpty(l))
return list(x)
else
return pair(head(l), push(tail(l), x))
}
function list (x) {
return pair(x, empty)
}
function listeach (l, f) {
if (isEmpty(l))
return null
else
(f(head(l)), listeach(tail(l), f))
}
// make a list
let l = list(1) // (1)
// push an item on the end
l = push(l, 2) // (1 2)
// push another item on the end
l = push(l, 3) // (1 2 3)
// display each item of the list
listeach(l, function (x) {
console.log(x)
})
closing remarks
It appears as tho you can use an Object in lieu of an Array. The accepted answer (at this time) shows a very narrow understanding of how an object could be used to solve your problem. After this contrived demonstration, are you confident that you are using Objects properly and effectively?
Do you know how to implement an object? Could you fulfill this contract (below)? What I mean by that, is could you write the functions object, set, and get such that the following expressions evaluated to their expected result?
In case it's not obvious, you're not allowed to use Object to make it happen. The whole point of the exercise is to make a new data type that you don't already have access to
m = object() // m
set(m, key, x) // m
get(m, key) // x
set(m, key2, y) // m
get(m, key2) // y
set(m, key3, set(object(), key4, z)) // m
get(get(m, key3), key4) // z
I'll leave this as an exercise for you and I strongly encourage you to do it. I think you will learn a lot in the process and develop a deep understanding and appreciation for what higher-level data types like Array or Object give to you
Since this is a homework I feel like I shouldn't solve it for you, but rather help you in the right direction.
Like Slasher mentioned you can use objects
With JavaScript object one book would look something like
const book = {
title: 'my awesome title',
type: 'novel'
};
book is the object
title is a property with a value 'my awesome title'
type is a property with a value 'novel'
But objects can also have other objects as values. Something like
const BookShelf= {
Book1: {
Title: 'my awesome title',
Type: 'novel'
},
Book2: {
Title: 'my horrible title',
Type: 'sci-fi'
}
};
You can reference the books in the bookshelf in two ways
const book1 = BookShelf.Book1 // Returns the book1 object
const title1 = Book1.Title; // Get the title
const sametitle = BookShelf.Book1.Title // Returns title for book1, same as above.
You can also use brackets:
const book1 = BookShelf['Book1'];
const title1 = BookShelf['Book1']['Title];
You can even make new properties on a object like this:
const Book3 = {
Title: 'running out of ideas'
Type: 'memoir'
};
BookShelf['Book3'] = Book3;
Now the BookShelf has a Book3 property. So your BookShelf object looks like
const BookShelf= {
Book1: {
Title: 'my awesome title',
Type: 'novel'
},
Book2: {
Title: 'my horrible title',
Type: 'sci-fi'
},
Book3 = {
Title: 'running out of ideas'
Type: 'memoir'
};
};
That should get you started :)
JavaScript Objects is a good way to go
1- define a new object:
var myVar = {};
or
var myVar = new Object();
2- usage
// insert a new value, it doesn't matter if the value is a string or int or even another object
// set a new value
myVar.myFirstValue="this is my first value";
// get existing value and do what ever you want with it
var value = myVar.myFirstValue

Group by in javascript or angularjs

I just want to do sum value column based on the Year and my data is below, but I don't know how to do this either using angular(in script) or javascript.
[
{"Year":2013,"Product":"A","Value":0},
{"Year":2013,"Product":"B","Value":20},
{"Year":2013,"Product":"A","Value":50},
{"Year":2014,"Product":"D","Value":55},
{"Year":2014,"Product":"M","Value":23},
{"Year":2015,"Product":"D","Value":73},
{"Year":2015,"Product":"A","Value":52},
{"Year":2016,"Product":"B","Value":65},
{"Year":2016,"Product":"A","Value":88}
]
I want to perform the sum on Value column and remove Product column as well.
Thanks
Edit As commenters have pointed out, this doesn't even require Lodash. Been using Lodash so much for current project I forgot reduce is built in. :-)
Also updated to put data in desired form [{"yyyy" : xxxx},...].
This code will accomplish this:
var data = [{"Year":2013,"Product":"A","Value":0},{"Year":2013,"Product":"B","Value":20},{"Year":2013,"Product":"A","Value":50},{"Year":2014,"Product":"D","Value":55},{"Year":2014,"Product":"M","Value":23},{"Year":2015,"Product":"D","Value":73},{"Year":2015,"Product":"A","Value":52},{"Year":2016,"Product":"B","Value":65},{"Year":2016,"Product":"A","Value":88}];
var sum = data.reduce(function(res, product){
if(!(product.Year in res)){
res[product.Year] = product.Value;
}else{
res[product.Year] += product.Value;
}
return res;
}, {});
result = [];
for(year in sum){
var tmp = {};
tmp[year] = sum[year];
result.push(tmp);
}
console.log(result);
RESULT:
[{"2013" : 70}, {"2014" : 78}, {"2015" : 125}, {"2016" : 153}]
ORIGINAL ANSWER
The easiest way I can think of to do this is with the Lodash Library. It gives you some nice functional programming abilities like reduce, which basically applies a function to each element of an array or collection one by one and accumulates the result.
In this case, if you use Lodash, you can accomplish this as follows:
var data = [{"Year":2013,"Product":"A","Value":0},{"Year":2013,"Product":"B","Value":20},{"Year":2013,"Product":"A","Value":50},{"Year":2014,"Product":"D","Value":55},{"Year":2014,"Product":"M","Value":23},{"Year":2015,"Product":"D","Value":73},{"Year":2015,"Product":"A","Value":52},{"Year":2016,"Product":"B","Value":65},{"Year":2016,"Product":"A","Value":88}];
result = _.reduce(data, function(res, product){
if(!(product.Year in res)){
res[product.Year] = product.Value;
}else{
res[product.Year] += product.Value;
}
return res;
}, {});
This yields:
{
"2013": 70,
"2014": 78,
"2015": 125,
"2016": 153
}
Basically, what we're telling Lodash is that we want to go through all the elements in data one by one, performing some operation on each of them. We're going to save the results of this operation in a variable called res. Initially, res is just an empty object because we haven't done anything. As Lodash looks at each element, it checks if that Product's year is in res. If it is, we just add the Value to that year in res. If it's not, we set that Year in res to the Value of the current product. This way we add up all the product values for each year.
If you want to try it out you can do it here:
Online Lodash Tester
Cheers!
You could do this using plain JavaScript. We use an object that will hold the results and the forEach array method. The object that would hold the results would have as keys the years and as values the sums of the corresponding values.
var data = [
{"Year":2013,"Product":"A","Value":0},
{"Year":2013,"Product":"B","Value":20},
{"Year":2013,"Product":"A","Value":50},
{"Year":2014,"Product":"D","Value":55},
{"Year":2014,"Product":"M","Value":23},
{"Year":2015,"Product":"D","Value":73},
{"Year":2015,"Product":"A","Value":52},
{"Year":2016,"Product":"B","Value":65},
{"Year":2016,"Product":"A","Value":88}
];
groupedData = {};
data.forEach(function(item){
var year = item.Year;
var value = item.Value;
if(groupedData.hasOwnProperty(year)){
groupedData[year]+=value;
}else{
groupedData[year]=value;
}
});
console.log(groupedData);

Add objects to JSON

I have a JSON that looks like this:
{
"__v":0,
"_id":"526a7b9c1affd1401d000001",
"ranStr":"azsuC2Ers0qTEcpzS8Jrs1pZ7MQH0goa",
"userId":{
"username":"t",
"_id":"51e11b28418dcfd01f000002"
},
"meta":{
"numberComments":0,
"favs":0,
"views":112
},
"enddate":"2014-01-31T00:00:00.000Z",
"startdate":"2013-10-25T00:00:00.000Z",
"comments":[],
"categories":[],
"fileurl":[],
"telephone":"1234567890"
}
When I add an object to it:
addObj[obj.length] = saveobject;
the previous content gehts replaced.
When I make an array out of it and push the object:
addObj = [loadedJSON];
addObj.push(saveObj);
I get this after the first
[Object]
after the second so fare so good
[Object, Object]
and after the third it gets messed up
[Array(2), Object]
What do I miss?
I hope some one can help with this?
The way I hoped it would look like is this.
[Object, Object, Object, ...and so on]
EDIT
to be More specific
when I add a new Object I load the JSON file in a variable and then I try to add the new Object.
Which works for the first two objects but the third one is added to the first object so that I got this result.
[Array(2), Object]
I dont want it nested like this! But how do I get it like this?
[Object, Object, Object].
EDIT
So eventually you all were right I just mixed up the array when i loaded it the second time every thing is fine now thank for pointing me in the right direction.
on the first time:
var a= [];
var b= {};
b= 'some things';
a.push(b);
and wenn a.length != null
b= 'the rest';
a.push(b);
and now everything is just as expected!
As far as I understand it, this has nothing to do with JSON.
It seems you want to have an array storing successive instances of a given object (that happens to have been encoded in JSON at some point, but for the problem at hand we could not care less).
First, create a sorage array.
Then push each new instance into it.
var storage = []; // your storage array, initially empty
// ....
while (some_guy_wants_to_send_me_something ())
{
var new_object = get_what_the_guy_sent_me_that_happens_to_be_JSON_encoded();
storage.push (new_object);
}
EDIT:
If you use a button:
var storage = []; // your storage array, initially empty
// ....
function add_whatever_object ()
{
var new_object = get_what_the_guy_sent_me_that_happens_to_be_JSON_encoded();
storage.push (new_object);
}
// HTML
<button type="button" onclick='add_whatever_object();'>
I still don't see where the catch is.
check the if it is an array:
Array.isArray(loadedJSON) //true
do this:
loadedJSON.push(saveObj);
if it was not an array push it to an array:
var myarray = [];
myarray.push(loadedJSON);
an then push your other object:
myarray.push(saveObj);
an so on:
myarray.push(otherObj);
I am a little unclear on what you actually want, but based on a little speculation I was able to write the following code for you. I hope this will solve your problem.
var a ={
"__v":0,
"_id":"526a7b9c1affd1401d000001",
"ranStr":"azsuC2Ers0qTEcpzS8Jrs1pZ7MQH0goa",
"userId":{
"username":"t",
"_id":"51e11b28418dcfd01f000002"
},
"meta":{
"numberComments":0,
"favs":0,
"views":112
},
"enddate":"2014-01-31T00:00:00.000Z",
"startdate":"2013-10-25T00:00:00.000Z",
"comments":[],
"categories":[],
"fileurl":[],
"telephone":"1234567890"
};
var b ={
"__v":0,
"_id":"526a7b9c1affd1401d000001",
"ranStr":"azsuC2Ers0qTEcpzS8Jrs1pZ7MQH0goa",
"userId":{
"username":"t",
"_id":"51e11b28418dcfd01f000002"
},
"meta":{
"numberComments":0,
"favs":0,
"views":112
},
"enddate":"2014-01-31T00:00:00.000Z",
"startdate":"2013-10-25T00:00:00.000Z",
"comments":[],
"categories":[],
"fileurl":[],
"telephone":"1234567890"
};
var c ={
"__v":0,
"_id":"526a7b9c1affd1401d000001",
"ranStr":"azsuC2Ers0qTEcpzS8Jrs1pZ7MQH0goa",
"userId":{
"username":"t",
"_id":"51e11b28418dcfd01f000002"
},
"meta":{
"numberComments":0,
"favs":0,
"views":112
},
"enddate":"2014-01-31T00:00:00.000Z",
"startdate":"2013-10-25T00:00:00.000Z",
"comments":[],
"categories":[],
"fileurl":[],
"telephone":"1234567890"
};
var ObjArr = [];
ObjArr.push(a);
ObjArr.push(b);
ObjArr.push(c);
console.log(ObjArr);
Here is the fiddle to it => http://jsfiddle.net/rB3Un/

viewer.loadImageFromJSON with variable not working

I have the following javascript that works perfectly good (with jquery):
function(test) {
var neuroimages = viewer.loadImageFromJSON('../data/new/res_neg_subj_val_5.nii.json', 'neg_subj_val_5', 'hot and cold');
return neuroimages;
};
Now I want to use a variable (lets say picture) instead of the '../data/new/res_neg_subj_val_5.nii.json', 'neg_subj_val_5', 'hot and cold' and format the code accordingly:
function(test) {
picture = "'../data/new/res_neg_subj_val_5.nii.json', 'neg_subj_val_5', 'hot and cold'";
neuroimages = viewer.loadImageFromJSON(picture);
return neuroimages;
};
This does not work.
Neither does this:
function(test) {
pic1 = "'../data/new/res_neg_subj_val_5.nii.json', 'neg_subj_val_5', 'hot and cold'";
pic2 = "'neg_subj_val_5'";
pic3 = "'hot and cold'";
neuroimages = viewer.loadImageFromJSON(pic1, pic2, pic3);
return neuroimages;
};
What am I doing wrong there?
I tried google and several sites with no success. Not to mention that I'm quiet a beginner with Java and already near insanity.
You are almost right with the second example. Here you should only specify one piece of data for each variable (at least in your case, but there are ways to specify many pieces of data in a single variable such as arrays and objects). Also you only need to have one set of quotes surrounding each string (doesn't matter whether they are single or double quotes as long as they match). Also, precede your variables with the 'var' keyword unless you want them to be global.
function(test) {
var pic1 = "../data/new/res_neg_subj_val_5.nii.json";
var pic2 = "neg_subj_val_5";
var pic3 = "hot and cold";
neuroimages = viewer.loadImageFromJSON(pic1, pic2, pic3);
return neuroimages;
};
Making your first attempt work is a little more tricky as you are passing an array to a function that expects three distinct variables. You do it like this:
function(test) {
var picture = ['../data/new/res_neg_subj_val_5.nii.json', 'neg_subj_val_5', 'hot and cold'];
neuroimages = viewer.loadImageFromJSON.apply(viewer, picture);
return neuroimages;
};
You're trying to initialize an array here, but you need to have a string instead. Try changing this:
picture = "'../data/new/res_neg_subj_val_5.nii.json', 'neg_subj_val_5', 'hot and cold'";
to:
picture = "'../data/new/res_neg_subj_val_5.nii.json';
You are not specifying if viewer.loadImageFromJSON() can accept an array, instead of a string. If it can, you could do something like:
picture = ['../data/new/res_neg_subj_val_5.nii.json', 'neg_subj_val_5', 'hot and cold'];
Check here on how to initialize arrays in Javascript:
http://www.w3schools.com/js/js_obj_array.asp
If you need more information on the issue, please attach the code for loadImageFromJSON(), so that we know how this function handles input and output

Categories

Resources