override array length in javascript - javascript

I got an idea to override javascript array length value and wants to return any random value.
let's say..
a=[56,78,89,200,800]
b=['a','b','f']
a.length = 2 ; //should give me only 2;
b.length = 2 ; //also should give 2
Is it possible to change length property and is there any tweaks to change the splice or slice method also.

Array.length is a protected property, only read; is a bad idea try to change it.
Better you can create your own class; example:
var oArray = function (aArr){
oRet = {};
for(var i = 0, aArrL = aArr.length; i < aArrL; i++){
oRet[i] = aArr[i];
}
oRet.length = 2;
return oRet;
};
a= new oArray([56,78,89,200,800]);
b=['a','b','f'];
console.log(a.length);
console.log(b.length);
a is a custom class, b is standard JavaScript Array.

Related

Possible to use an object property as a method's argument

Basically I am trying to create an object property that will dynamically create an array based on the constructor. The following works if I remove the constructor and simply set testArray.length to some integer. But stops working when I try setting length with a constructor.
class TestArray {
constructor(length) {
this.length = length;
}
buildArray = function(length) {
let array = [];
for (let i = length; i > 0; i--) {
array.push("_");
}
return array;
}
array = this.buildArray(this.length);
}
let testArray = new TestArray(2);
console.log(testArray.array);
let testArray2 = new TestArray(2);
console.log(testArray2.array);
//[] is logged. Desired out put is ['_', '_']
Do I have syntax issue or a logic issue? Is there a plain better way to do this?
Class fields - assignments directly inside a class body - run before the body of the constructor runs (assuming there's no superclass). Your code is equivalent to
class TestArray {
constructor(length){
array = this.buildArray(this.length);
this.length = length;
}
See the problem? this.length hasn't been assigned to at the time you call buildArray, so it's undefined.
Remove the class field, and put that logic in the constructor, so that you can make use of the constructor's argument. Might as well ditch this.length entirely at that point too, it doesn't look to be doing anything useful.
class TestArray {
constructor(length){
this.array = this.buildArray(length);
}
buildArray = function(length){
let array = [];
for(let i = length ; i > 0; i--){
array.push("_");
}
return array;
}
}
let testArray = new TestArray(2);
console.log(testArray.array);

What does this Javascript code mean?

I am trying to do a algorithm challenge. I saw this code from one of the completed answers. I am new to javascript so I am not completely sure of the code. I know that the first section of code pretty much takes the input and makes it to a map. Then init a matchingPair array and a counter. I am pretty much lost at the for loop section. Not too sure what matchingPairs[""+c[i]] = matchingPairs[""+c[i]] || 0; does. I am guessing the for loop is adding all the elements of matching pairs to the array and adding to counter.
function main() {
var n = parseInt(readLine());
c = readLine().split(' ');
c = c.map(Number);
var matchingPairs = {};
var matchingPairCount = 0;
for(var i=0; i< c.length; i++) {
matchingPairs[""+c[i]] = matchingPairs[""+c[i]] || 0;
matchingPairs[""+c[i]] += 1;
if (matchingPairs[""+c[i]] % 2 === 0) {
matchingPairCount += 1;
}
}
console.log(matchingPairCount);
}
A simpler example
a = {}
a["b"] = a["b"] || 0
console.log(a) // {b: 0}
a is set to an empty object. a["b"] is not yet set to anything, so when accessed it returns undefined.
Undefined is falsey - so this effectively sets a["b"] to 0.
Take another example;
a = {b: 5}
a["b"] = a["b"] || 0
console.log(a) // {b: 5}
The only difference in this example is that a["b"] is truthy (ie, it returns 5 rather than undefined).
This is a javascript way of setting a variable to a value only if it hasn't already been set to something else.
A string of space delimited numbers is supplied.
The counts of each number are calculated.
Each time a count is even then the matchingPairCount is incremented.
In short: it is counting pairs of matching numbers.
n is not used?

How to get length of string in javascript without using native length method

I am working on a practice problem:
Return the length of a string without using javascript's native string.length method.
The only ways I could think of would be substring or slice, but I'm stumped.
You can loop over the string, testing to see whether there is a non-undefined value at each index (as soon as you get an undefined value you've run past the end of the string):
function strLength(s) {
var length = 0;
while (s[length] !== undefined)
length++;
return length;
}
console.log(strLength("Hello")); // 5
console.log(strLength("")); // 0
(I'm assuming that if you're not allowed to use the native string .length property that you probably shouldn't use the array .length property either with str.split("").length...)
Given that this is a practice problem, I suspect the OP may not want ES6/ES2015, but, just in case that's an option, and/or for whoever else is looking at this, here's a concise modern approach:
const str = "Hello world!";
console.log([...str].reduce(a => a+1, 0));
(When I posted this, no other answer had proposed this solution. However, I had missed the fact that #MarkoGrešak had essentially proposed this exact solution in a comment to another question.)
You can use spread element, Array.prototype.keys() iterator, Array.prototype.pop()
var str = "abc";
var len = [...[0,...str].keys()].pop();
console.log(len, str.length);
The briefest have been able to achieve so far using Object.keys(), Array.prototype.pop() and checking for empty string. Approach could probably be improved further.
var len = str === "" ? 0 : +Object.keys(str).pop()+1;
#nnnnnnn utilizes the two methods at above far exceeding the initial attempt in brevity and addressing case of empty string.
var len = +Object.keys(str+' ').pop();
One way would be iterating through a split string like so:
var count = 0;
Array.from("string here".split("")).forEach(function(){count++});
Tip from Marko below in the comments to use the reduce function to shorten it to:
var count = Array.from("string here".split("")).reduce(function(count){return count+1}, 0);
You could use array.length so you answer the question not using the native string.length.
var Str = "Hello world!";
const CountAr = Str.split("").length;
console.log(CountAr);
/*12*/
function stringLength(str) {
var count = 0;
var index = 0;
while(string[index] !== undefined){
count += 1;
index += 1;
}
return count;
}
I think this will work. If you start with '', it won't go into the while loop, and you'll just return 0.
function getStringLength(string) {
var idx = 0;
while (string[idx] !== undefined) {
idx += 1;
}
return idx;
}
This will work.
function length(str) {
str = str.split('');
var length = 0;
str.forEach(function(element) {
length++;
});
return length;
}
length('hello'); // output 5
Yet another way to do it
function getStringLength(str){
var count = 0;
for(var letter in str){
count += 1;
}
return count;
}
console.log(getStringLength('Mississippi')) // 11
console.log(getStringLength('')) // 0
The for in loop is the way to go I think. You can use slice or substring but for in loops can count strings easily too.
function getStringLength(string) {
var length = 0;
for (var i in string){
length++;
}
return length;
}
This is the solution I came up with
I have used a while loop for getting the length of the input
Sharing Two approaches with a while loop
Approach no 1
function getLength(input) {
if(!input){
return 'please provide input'
}
let i = 0;
while (true) {
if (input[i]) {
i += 1
}else{
break
}
}
return i
}
console.log(getLength([1, 5, 3, 7, 8])) // 5
console.log(getLength("Hare Krishna")) // 12
Output
5 (for array)
12 (for string)
Approach no 2
function getLength(input){
let i = 0;
while(input[i] !== undefined){
i++;
}
return i
}
console.log(getLength([1,2,3,48,8,9])) // 6
Output
6 (for array)
function getStringLength(string) {
// Do NOT use any native 'length' methods.
// You might consider using 'substring' or 'slice' as alternatives.
let i = 0;
while (Number(string.slice(i, i+1)) !== 0) {
i++;
} return i;
}
var output = getStringLength('hello');
console.log(output); // --> 5

Cannot set property '0' of undefined in 2d array

I know this has been asked a lot of times, but how do I fix exactly this thing?
I have a map[][] array (contains tile ids for a game) and I need to copy it to pathmap[][] array (contains just 0's and 1's, it is a path map), however when I do so..
function updatepathmap(){
pathmap = [];
var upm_x = 0;
while (upm_x < map.length){
var upm_y = 0;
while (upm_y < map[upm_x].length){
pathmap[][]
if (canPassthrough(map[upm_x][upm_y])) {
pathmap[upm_x][upm_y] = 1;
} else {
console.log(upm_x);
console.log(upm_y);
pathmap[upm_x][upm_y] = 0;
}
upm_y++;
}
upm_x++;
}
console.log(map);
console.log(pathmap);
}
..it gives me Cannot set property '0' of undefined typeerror at line pathmap[upm_x][upm_y] = 0;
Despite the foo[0][0] syntactic sugar, multi-dimensional arrays do not really exist. You merely have arrays inside other arrays. One consequence is that you cannot build the array in the same expression:
> var foo = [];
undefined
> foo[0][0] = true;
TypeError: Cannot set property '0' of undefined
You need to create parent array first:
> var foo = [];
undefined
> foo[0] = [];
[]
> foo[0][0] = true;
true
You can determine whether it exists with the usual techniques, e.g.:
> var foo = [];
undefined
> typeof foo[0]==="undefined"
true
> foo[0] = true;
true
> typeof foo[0]==="undefined"
false
I would have thought pathmap[][] was a syntax error, I'm surprised you're not seeing one.
Before you can use an array at pathmap[upm_x], you must create an array at pathmap[upm_x]:
pathmap[upm_x] = [];
This would be the first line in your outer while, so:
while (upm_x < map.length){
pathmap[upm_x] = [];
// ...
Remember that JavaScript doesn't have 2D arrays. It has arrays of arrays. pathmap = [] creates the outer array, but doesn't do anything to create arrays inside it.
Side note:
var upm_x = 0;
while (upm_x < map.length){
// ...
upm_x++;
}
is an error-prone way to write:
for (var upm_x = 0; upm_x < map.length; upm_x++){
// ...
}
If you use while, and you have any reason to use continue or you have multiple if branches, it's really easy to forget to update your looping variable. Since looping on a control variable is what for is for, it's best to use the right construct for the job.
Side note 2:
Your code is falling prey to The Horror of Implicit Globals because you don't declare pathmap. Maybe you're doing that on purpose, but I wouldn't recommend it. Declare your variable, and if you need it outside your function, have your function return it.
Side note 3:
map would make this code a lot simpler:
function updatepathmap(){
var pathmap = map.map(function(outerEntry) {
return outerEntry.map(function(innerEntry) {
return canPassthrough(innerEntry) ? 1 : 0;
});
});
console.log(map);
console.log(pathmap);
}

Object.create to create an object with costructor

I am learning Javascript and I am a C++ programmer. I have tried creating an object with a constructor with object.create and here is the result:
var PlayGround ={
initGrid : function(N) {
this.N=N;
this.grid = new Array(N);
for (var i = 0; i < N; i++) {
this.grid[i] = new Array(N);
for (var j = 0; j < N; j++) {
this.grid[i][j] = false;
}
}
return true;
}
};
var PlayGround_property = {
N:{
value: 100,
writable:true
},
grid:{
value:null,
writable:true
}
}
var board= Object.create(PlayGround, PlayGround_property);
It works as I want: the object board contains the object grid, and now I can use the set and get keyword to define the behaviour of the = and () operator.
Anyway I have read around the web that the
this
keyword in Javascript is not safe and I want to be sure that it is referring always to the board object and not to the global window object. Is there a way or I am overthinking?
Other question, are there other ways to write object with a constructor (and maybe other members) in Javascript?
I want to be sure that [this] is referring always to the board object
A function's this is set either by how you call the function, or bind. So just make sure you call methods the right way. If you always call functions as methods of board, then this within the methods will always reference board.
If you are only going to have one instance of board, there doesn't seem much point in using a constructor. If you have multiple instances of board, then you want this to reference the particular instance that called the method so you don't want to fix this using bind.
Crockford just doesn't like the use of new, so encouraged Object.create, it fits his idea of how inheritance should work.
Your pattern could be rewritten to use a constructor something like:
function PlayGround (N) {
this.N = N;
this.grid = []; // Use array literal, it's less to type
for (var i = 0; i < N; i++) {
this.grid[i] = [];
for (var j = 0; j < N; j++) {
this.grid[i][j] = false; // Not sure why you bother with this
}
}
}
var board = new Playground(100);
I'm not exactly sure what you're doing, but that should be close. Note that javascipt is loosely typed, so only initialise variables and properties if you have something useful to assign. Variables are created with a value of undefined, Array properties are only created if you actually assign something to them, creating an array with length N does not create any indexes, e.g.
var arr = new Array(10);
console.log(arr.length); // 10
console.log(arr.hasOwnProperty(0)); // false

Categories

Resources