In javascript, I am creating an array with some values in it. The list of values is relatively long, and results in the single line of code appearing on two lines on most screens. For example, the line of code is:
var fieldNames = ['firstName', 'lastName', 'phoneNumber', 'emailAddress', 'hotelName', 'roundTrip', 'origin', 'departureDate', 'departureTime', 'returnDate', 'returnTime'];
Is there a preferred way to format this line so it's more readable? Should each value in the array be on its own line?
If the goal is more readable code, then putting each element separately on its own line works well.
For example, as is, if you make a change to an element in the array and commit to git, the whole line will show up as being changed in the diff. It is difficult for others to see exactly which element changed.
If each element is on its own line, and you make a change to an element then commit to git, then only the line with the changed element will show up in the diff. It is then obvious which element was changed.
This is what I usually do:
var fieldNames = [
'firstName', 'lastName', 'phoneNumber', 'emailAddress', 'hotelName',
'roundTrip', 'origin', 'departureDate', 'departureTime', 'returnDate',
'returnTime'
];
This is what I do. This may or may not be a good idea.
At least for me, it helps me to understand where the array starts and stops and what variable it belongs to.
We use require.js in our project and sometimes it happens that a module requires a lot of dependencies so our code looks like this:
require([
module1,
module2,
module3,
module4,
module5,
module6
], function(
module1_obj,
module2_obj,
module3_obj,
module4_obj,
module5_obj,
module6_obj
){
...
});
Because we have to define 2 lists that are really long we format it as a column, 1 item in one line, this way when we delete a dependency we can easily delete it in both columns and see that both have identical count of items.
Clarification: first array in require.js defines dependencies and the second gives an object to use of that dependency that is the reason why there are two.
Benefits of not placing any item in first line
var foo = [ // <-- Not having an element on this line.
1,
2,
3
];
Is that then the array is defined in the same fashion as object is usually:
var bar = {
iAmAProperty: "YAY"
};
And in version control you can clearly see if the content of object/array is edited or the name of the object/array
var fieldNames = ['firstName', 'lastName', 'phoneNumber', 'emailAddress',
'hotelName', 'roundTrip', 'origin', 'departureDate', 'departureTime',
'returnDate', 'returnTime'];
Related
I need to dynamically create a multidimensional javascript array that matches this layout:
array_answers[0][1]:"yes"
array_answers[1][2]:"no"
array_answers[2][2-subquestion]:"text input"
array_answers[3][8]:"yes"
array_answers[4][8-subquestion]:"text input"
The first "[ ]" defines what question it is on the page (out of totalInputs)
The second "[ ]" defines what question from the database this is (questions already in order to match the corresponding input)
and the information following is the input I am trying to add
I have attempted to the following with no luck.
for(var i = 0; i < totalInputs; i++) {
array_answers.push([i]);
array_answers[i].push([questions[i]]);
array_answers[i][0] = "yes, no, or other text";
}
The last line is where it falls apart. It would make sense to me that I should be able to use [0] to indicate that I want the first array to be given this value but with no avail.
I have also tried:
for(var i = 0; i < totalInputs; i++) {
array_answers.push([i]);
array_answers[i].push([questions[i]]);
array_answers[i][questions[i]] = "yes, no, or other text";
}
but this gives me lots of empty arrays for all the numbers from 0 to whatever the value of questions[i] is.
What am I missing or is there a simpler way to do this in jQuery while still conforming to the target layout?
If I understand you correctly, you are trying to store questions and prompts (maybe?) together in a multi dimensional array. let me suggest a different way that should work.
const array_answers = questions.map(q => [q, "yes, no, other text"]);
This may be what you want
I am still not 100% sure of what you need, but i thought I would write an answer with my assumptions, that I can update as the information improves.
The first "[ ]" defines what question it is on the page (out of
totalInputs)
This part looks like you are correct, and need to use an array. But an array is just a list of "things", in your case, questions. So where you have this line:
array_answers.push([i]);
I'm not sure it is doing what you are expecting. This is adding a new array item, which is in itself an array, that contains a single number. So if totalInputs is 3, then that first line will result in this structure:
array_answers= [[0],[1],[2]]
I think what you actually might intend here is to simply house an array of question details. Now by the complexity of your keys listed for the second dimension, it looks like an object would be more appropriate.
The second "[ ]" defines what question from the database this is
(questions already in order to match the corresponding input)
So lets go ahead and create a single question.
var question = {
anythingYouWant: 'here',
2: 'even numeric keys'
}
// you can access the values in these ways
console.log(question.anythingYouWant)
console.log(question[2])
console.log(question['anythingYouWant'])
Now once you have a question object, you can then add it to your array_answers array with push.
array_answers.push(question).
If you have two identical questions like the one above, your array will look like this:
array_answers = [{
anythingYouWant: 'here',
2: 'even numeric keys'
},{
anythingYouWant: 'here',
2: 'even numeric keys'
}]
In order to access the questions within the array, you can simply use their index:
// access second question
var secondQuestion = array_answers[1]
You can read these links to learn more about objects & arrays
In trying to create a sortable table, I am sorting the underlying array of data:
var g = [
[ 'First Name', 'Last Name', 'Id', 'Age'],
[ 'Joe', 'Blogs', '1', 24],
[ 'Fred', 'Frog', '2', 18],
];
I want to sort everything except the header.
g = g.sort(mycomparison);
is no good, though I could change the comparison routine to always put element[0] in front of everything else.
Instead, I would like to sort everything except the header. The following seems to do what I want, but I wanted to know if there is a better way to express this in javascript. I want to sort the last n-1 elements.
g = g.slice(0,1).concat(g.slice(1,g.length-1).sort(mycomparison))
If you are interested in another way which looks a bit tidier, see this following underscore.js way:
g = [].concat(_.first(g), _sort(_.tail(g), mycomparison ));
Using underscore does not help improving performance but it just simplifies and makes your code a bit more readable. From the example above, I believe it makes sense to people who even don't usually use underscore.
It's straightforward and semantic so people read it and understand instantly that it splits the first, and the rest of array g, sort the rest and re-join them. (To me it looks more readable than vanilla JavaScript)
I believe that what I'm trying to do is declare several arrays within an array.
In a text document, I have the following:
"一","いち","one"
"二","に","two"
"三","さん","three"
"四","し・よん","four"
"五","ご","five"
Which I want to automatically place into an array with the items assigned as groups of 3, so for instance set_one[0][1] would be "いち", set_one[3][2] would be "four", so on.
For the life of me, I cannot figure out how to even read the values line by line from the plain text document, let alone try to automatically assign them into arrays.. so I tried manually. I have:
var set_one = new Array(new Array("一", "いち","one"), new Array("二", "に","two", new Array("三", "さん","three", new Array("四", "よん・し","four", new Array("五", "ご","five");
Which, when document.write(set_one[3][2]); is called, nothing happens what-so-ever.. I even tried a for loop to see if anything exists in the (set_one) array at all, though as far as I can tell, nothing does.
It's difficult working on this windows machine to say the least, as I have no debugging tools available, and it doesn't have an active Internet connection! What am I doing wrong? Is there a better way of doing this? Is it even possible to read the values into an array automatically line-by-line, then assign the values to individual arrays based on the comma values?
You're not creating the array correctly. For example, when you have:
new Array("二", "に","two", new Array("三", "さん","three"))
You are actually creating a single-element array, in which the 3rd position is itself another array. Either use:
new Array (new Array("二", "に","two"), new Array("三", "さん","three"))
Or the much simpler, and less confusing way of creating arrays in JavaScript:
var set_one = [
[ "一","いち","one" ],
[ "二","に","two" ],
[ "三","さん","three" ],
[ "四","し・よん","four" ],
[ "五","ご","five" ]
];
set_one[0][1]; // いち
var set_one = [
["一","いち","one"],
["二","に","two"],
["三","さん","three"],
["四","し・よん","four"],
["五","ご","five"]
];
I am building a web application in which I build a sorted list out of an object like this:
{head: {subhead: [list_items], subhead: [list_items]}, head: {subhead: [list_items]}}.
My problem is that I have to ensure the headings and subheading always follow in a certain order. This is complicated by the fact that headings and subheadings that may be added later on also need to follow this order. So the only way I could think to inform the parser of the order would be to give it some data like this:
{heads: [head1, head2, head3], subheads: {head1: [subhead1_1, subhead1_2], head2: [subhead2_1, subhead2_2, subhead2_3]}},
but that strikes me as overly verbose and repeating data that would be in the original data structure.
You might as well use an array (or your own structure) for this since you want it to be ordered. Your own structure might look like:
function Head(name) {
this.name = name;
this.arr = [];
}
So instead of the structure:
var thing = {
food: {fruit: [apples, oranges], vegetables: [carrots, peas]},
animals: {domestic: [cat, dog], wild: [lion, bear]}
}
You might do:
var thing = [new Head('food'), new Head('animals')]
Then:
thing[0].arr.push('apples');
thing[0].arr.push('oranges');
etc.
Of course you don't have to make a class, since you can actually attach properties to arrays in javascript. But making the datastructure would be a bit more of a pain.
Can you suggest me an algorithm for filtering out data.
I am using javascript and trying to write out a filter function which filters an array of data.I have an array of data and an array of filters, so in order to apply each filter on every data, I have written 2 for loops
foreach(data)
{
foreach(filter)
{
check data with filter
}
}
this is not the proper code, but in short that what my function does, the problem is this takes a huge amount of time, can someone suggest a better method.
I am using the Mootools library and the array of data is JSON array
Details of data and Filter
Data is JSON array of lets say user, so it will be
data = [{"name" : "first", "email" : "first#first", "age" : "20"}.
{"name" : "second", "email" : "second#second", "age" : "21"}
{"name" : "third", "email" : "third#third", "age" : "22"}]
Array of filters is basically self define class for different fields of data
alFilter[0] = filterName;
alFilter[1] = filterEmail;
alFilter[2] = filterAge;
So when I enter the first for loop, I get a single JSON opbject (first row) in the above case.
When I enter the second for loop (filters loop) I have a filter class which extracts the exact field on which the current filter would work and check the filter with the appropriate field of the data.
So in my example
foreach(data)
{
foreach(filter)
{
//loop one - filter name
// loop two - filter email
// loop three - filter age
}
}
when the second loop ends i set a flag denoting if the data has been filtered or not and depending on it the data is displayed.
You're going to have to give us some more detail about the exact structure of your data and filters to really be able to help you out. Are the filters being used to select a subset of data, or to modify the data? What are the filters doing?
That said, there are a few general suggestions:
Do less work. Is there some way you can limit the amount of data you're working on? Some pre-filter that can run quickly and cut it down before you do your main loop?
Break out of the inner loop as soon as possible. If one of the filters rejects a datum, then break out of the inner loop and move on to the next datum. If this is possible, then you should also try to make the most selective filters come first. (This is assuming that your filters are being used to reject items out of the list, rather than modify them)
Check for redundancy in the computation the filters perform. If each of them performs some complicated calculations that share some subroutines, then perhaps memoization or dynamic programming may be used to avoid redundant computation.
Really, it all boils down to the first point, do less work, at all three levels of your code. Can you do less work by limiting the items in the outer loop? Do less work by stopping after a particular filter and doing the most selective filters first? Do less work by not doing any redundant computation inside of each filter?
That's pretty much how you should do it. The trick is to optimize that "check data with filter"-part. You need to traverse all your data and check against all your filters - you'll not going to get any faster than that.
Avoid string comparisons, use data models as native as possible, try to reduce the data set on each pass with filter, etc.
Without further knowledge, it's hard to optimize this for you.
You should sort the application of your filters, so that two things are optimized: expensive checks should come last, and checks that eliminate a lot of data should come first. Then, you should make sure that checking is cut short as soon as an "out" result occurs.
If your filters are looking for specific values, a range, or start of a text then jOrder (http://github.com/danstocker/jorder) will fit your problem.
All you need to do is create a jOrder table like this:
var table = jOrder(data)
.index('name', ['name'], { grouped: true, ordered: true })
.index('email', ['email'])
.index('age', ['age'], { grouped: true, ordered: true, type: jOrder.number });
And then call table.where() to filter the table.
When you're looking for exact matches:
filtered = table.where([{name: 'first'}, {name: 'second'}]);
When you're looking for a certain range of one field:
filtered = table.where([{age: {lower: 20, upper: 21}}], {mode: jOrder.range});
Or, when you're looking for values starting with a given string:
filtered = table.where([{name: 'fir'}], {mode: jOrder.startof});
Filtering will be magnitudes faster this way than with nested loops.
Supposing that a filter removes the data if it doesn't match, I suggest, that you switch the two loops like so:
foreach(filter) {
foreach(data) {
check data with filter
}
}
By doing so, the second filter doesn't have to work all data, but only the data that passed the first filter, and so on. Of course the tips above (like doing expensive checks last) are still true and should additionally be considered.