remove intermediary object from map object - javascript

I have a couple of these and think (know) that I'm doing something wrong (or could be simpler).
html:
<div class='item-to-select' data-global-id='55'>some</div>
var l=$(this).map(function(){
t=new Object();
t.global_id=$(this).data('global-id');
return t;
}).get();
var list=l[0]; // want to remove this
How would I remove this intermediary object? Or a better way
thx

If you mean that you don't want to have to define the l variable just so you can use it once in setting up your list variable you can do this:
var list = $(this).map(function(){
return {
global_id : $(this).data('global-id')
};
}).get()[0]; // note the [0] directly after .get()
The return from any function that returns an array (or array-like object) doesn't have to be assigned to a variable before you can use it. So:
var temp = someFuncReturnsArray();
console.log(temp[0]);
// can be replaced by
console.log(someFuncReturnsArray()[0]);
Of course if you need to do further processing on the returned array you need to put it in a variable. E.g., if you need to test its length, or if the function could possibly return null in some situations, etc. In the example above if an empty array was returned then obviously [0] will be undefined.
But if you only need the return value once you can just use it directly.
Note that I've removed the t variable from your code too. When creating an empty object it is considered good practice to say obj = {} rather than saying obj = new Object(). But you can create an object with properties in one step if the property values are already known. In the case of your function the t object you create isn't manipulated in any way other than adding a single property to it before you return it, so you can simply return an object literal directly instead of doing it in three steps.

The jQuery .get() method accepts an index.
So, you can write :
var list=$(this).map(function(){
t=new Object();
t.global_id=$(this).data('global-id');
return t;
}).get(0);

Related

Comparison between normal array vs generated by back-tick array

I am creating an array by two way.
my first way is creating an array normally
my second way is creating an array by using backticks function
let array=["1234"];
function createArrayByBakticks(obj)
{
return obj;
}
let backtickArray = createArrayByBakticks `1234`;// it's responding an array
console.log(array); //1st way and it returns an array
console.log(backtickArray ); //2nd way and it returns a same array
backtickArray.push(1);// but it's throwing an error while push a new value.
// Error: Uncaught TypeError: Cannot add property 1, object is not extensible
console.log(backtickArray);
Above both ways are return as a array data. But the second array is not supporting inbuilt function of array which is generated by back-ticks. WHY? And what is the difference between in the both ways?
createArrayByBakticks is used as a so-called tag function. The first argument passed to the function is an array containing all strings of the template literal.
If you dive deep into the language specification, section 12.2.9.3, then you will see the following step is performed after the array has been created:
Perform SetIntegrityLevel(template, "frozen").
This means that in your case objis frozen and no property can be added. That's why invoking push doesn't work.
You can confirm this by calling console.log(Object.isFrozen(backtickArray)).
The array returns from the function by value, meaning it's immutable.
If you use concat, you'll get a new copy of it, which you can modify:
let array = ["1234"];
function createArrayByBakticks(obj) {
return obj;
}
let backtickArray = createArrayByBakticks `1234`; // it's responding an array
console.log(array); //1st way and it returns an array
console.log(backtickArray); //2nd way and it returns a same array
let newArray = backtickArray.concat(1); // a new mutable array is generated
newArray.push(2); // so you can even keep modifying it
console.log(newArray);

JavaScript array as function input

I am be beginner in JavaScript, and do not know how to make a simple function with an array/vector as an input. This is the code I have:
function semGPA(credits) {
var c = credits.length;
return c;
}
I want to pass a list of numbers (ex. credits={3,4,5,6}), and have it tell me that there are 4 elements in the variable. So far, I have not found any built in functions that create a working function. Everything I try to use other than +-*/ results in a TypeError. Here it says the property "length" is undefined.
It's not entirely clear what you want. You can pass an array as credits and your function will work fine (although it's a bit pointless as is, since you can just directly call length on your array):
semGPA([1,2,3,4]); // returns 4
Perhaps you meant that you wanted to do something like this?
function semGPA() {
var c = arguments.length;
return c;
}
Which you can call like this:
semGPA(1,2,3,4); // returns 4
Which uses the arguments object which is a special object passed to functions that can be used to access all the arguments (including unnamed arguments) passed to a function.
As mentioned in the comments the example you have is an Object and not an array.
var array = [1,2,3,4,5]
var object = {1,2,3,4,5} ==> This is not a valid object in Javascript.
The object notation above expects a key-value pair. something like
var object = {1: 1, 2: 2, 3: 3}
The length property does not exist on an object. However, if you want to check the number of elements in an Object you can make use of the below code which is self explanatory:
var credits = {1:1,2:2,3:3,4:4}
function semGPA(credits) {
var creditKeysArray = Object.keys(credits); //this will give you an array of keys
var creditLength = c.length;
return creditLength;
}

How to translate a string to object notation

I'm working with a JSON validator that checks a give JSON object against a schema and returns errors if it doesn't match. One of the things I need to do is add missing attributes, but these could potentially be quite deep in the structure. The validator error returns the location of a missing attribute as a string in this format:
'data.thing1.thing2.thingN'
I can strip out the "data." bit easily enough, but I don't know how to translate the rest to correct object notation, in any depth. This is what I've got so far:
var attributeLineage = newField.split(".");
obj[attributeLineage[0]][attributeLineage[1]] = "";
So obviously this only works when there are only two levels of depth. I need to loop through the values in attributeLineage and link them all together to correctly construct the missing attribute in the given object, at any depth. How can this be done?
I might be missing something totally obvious, or going about it the wrong way, but I'm not sure how to proceed.
Using reduce() method get the reference of the inner object and update the property using last element in split array.
var newField = 'data.thing1.thing2.thingN';
// split the string
var attributeLineage = newField.split("."),
// get last element and remove it from splitted array
prop = attributeLineage.pop();
var ob = {
data: {}
};
// get the object reference
var obj = attributeLineage.reduce(function(o, k) {
// return if nested object is defined
// else define and return it
return o[k] || (o[k] = {}) && o[k];
}, ob);
// update the inner object property
obj[prop] = "hi";
console.log(ob);

Rewrite following piece of javascript code

I am trying to create a function that mimics Array.prototype.push.
It takes a variable number of arguments and pushes them into a specific array.
I have managed to do this with the following code:
var array=[];
function append(){
for(var i=0;i<arguments.length;i++)
array.push(arguments[i]);
}
Now my question is:Can I rewrite the append function without using "for loop"?
Thanks in advance.
If you need to get arguments array, you should use Array's slice function on an arguments object, and it will convert it into a standard JavaScript array:
var array = Array.prototype.slice.call(arguments);
You could use Array.prototype.push.apply
function append(){
// make arguments an array
var args = Array.prototype.slice.call(arguments);
// return the number of elements pushed in the array
return Array.prototype.push.apply(array, args);
}
So, what's happening here with args? We use Array.prototype.slice.call with arguments, the purpose being to make arguments an array, because it is a special object. Function.prototype.call is used to call a function with a specific context (aka this), and then the arguments to call the function with (comma separated). Conveniently, it appears that slice() looks at the length property of the this context, and arguments has one too, and when not empty, has properties from 0 to length -1, which allows slice to copy arguments in a new array.
You can rewrite this without a for loop, but you have to use a loop of some sort (you're working with multiple items, it's a necessity).
If you have access to ES6 or Babel, I would use something like:
function append(...args) {
return array.concat(args);
}
Without ES6, you need to work around the fact that arguments isn't a real array. You can still apply most of the array methods to it, by accessing them through the Array prototype. Converting arguments into an array is easy enough, then you can concat the two:
function append() {
var args = Array.prototype.map.call(arguments, function (it) {
return it;
});
return array.concat(args);
}
Bear in mind that neither of these will modify the global array, but will return a new array with the combined values that can be used on its own or assigned back to array. This is somewhat easier and more robust than trying to work with push, if you're willing to array = append(...).
Actually i honestly believe that push must be redefined for the functional JS since it's returning value is the length of the resulting array and it's most of the time useless. Such as when it's needed to push a value and pass an array as a parameter to a function you cant do it inline and things get messy. Instead i would like it to return a reference to the array it's called upon or even a new array from where i can get the length information anyway. My new push proposal would be as follows;
Array.prototype.push = function(...args) {
return args.reduce(function(p,c) {
p[p.length] = c;
return p
}, this)
};
It returns a perfect reference to the array it's called upon.

Arrays in JavaScript

While reading a book about JavaScript I stumbled across an example:
var names = new Array("Paul","Catherine","Steve");
var ages = new Array(31,29,34);
var concatArray;
concatArray = names.concat(ages);
My question is, why doesn't the variable concatArray need to be define as a new Array() in order to store the concatenated data for both arrays name and ages , but when I try to treat the concatArray as an array by adding another line of code "document.write(concatArray[0])", it works just like an array and shows me the data stored in the first element. I just wonder why I'm not declaring the concatArray as a new array, yet it still works as one.
You are declaring concatArray as a new array but the declaration is implicit. The concat function returns a new array which contains concatenated copies of the original two arrays. The type of concatArray is inferred from the return type of the concat function.
Variable don’t have a specific data type in Javascript like in other languages. You can assign a variable every value you want.
That means var concatArray; declares the variable but the value is undefined:
var concatArray;
alert(typeof concatArray === "undefined");
Only when assigning the return value of names.concat(ages) (an array) to concatArray it get’s that type:
var names = new Array("Paul","Catherine","Steve");
var ages = new Array(31,29,34);
var concatArray;
alert(typeof concatArray === "undefined");
concatArray = names.concat(ages);
alert(concatArray.constructor === Array);
Javascript doesn't care what the contents of the var are when it is declared; that is why you can declare var concatArray without needing to specify it as an array. Once you assign it a value and a type (as the result of the concat() function) javascript treats the var as an array.
Simply put, w3schools says it pretty concisely:
The concat() method is used to join two or more arrays.
This method does not change the existing arrays, it only returns a copy of the joined arrays.
w3schools
Looks like Andrew and Matthew beat me to it anyway.
Because Javascript is dynamically typed. A variable doesn't have a specifuc type, and an array is an object that you can assign to any variable.
When you declare a variable without assigning it a value, it just exists with an undefined value:
var answer;
// now the variable exists, but it doesn't have a value
answer = 42;
// now the variable has the numerical value 42
answer = "hello";
// now the numerical value has been replaced with the string value "hello"
answer = [];
// now the variable contains an empty array
answer[0] = 1337;
// now the variable contains an array that contains an item with the value 1337
answer = -1
// now the array is gone and the variable contains the value -1
I would make an answer slightly different of Andrew's one.
JavaScript variables are not strongly typed. You can put a string, then a number, then an object in the same variable. When you use the variable, the interpreter checks its current type is suitable for the usage you try to make. If you write:
var a = 45;
alert(a[0]);
a = [ 5 ];
alert(a[0]);
you will get successively undefined then 5.

Categories