Use Array.map on an 2-dimensional Array - javascript

So I have a 2-dimensional Array and want to use a "randomBool" function on each of the elements of the elements in the array.
The "randomBool" function just returns a random boolean:
const randomBool = () => Boolean(Math.round(Math.random()));
this would be the 2-dimensional Array, that I would input:
var test = [
["just","some","random","text"],
[1412,"test",1278391]
]
There is a working for-loop nested in a for-loop:
for (let el of test){
for(let i in el){
el[i] = randomBool();
}
}
I tried this:
test.forEach(el => el.map(el2 => randomBool()));
But it didn't work. Why?

You need to use two nested maps.
const randomBools = test.map(outer => outer.map(inner => randomBool()))
forEach is usually intended to iterate over each item in order to perform some kind of side effect without returning anything and without mutating the original array. For example, printing each item to the console.
map, on the other hand, is intended to take an array and return a new array of the same size, with the values transformed in some way, without mutating the original array. For example, uppercase all the words in a list.
Since you want to return a new 2 dimensional from your existing 2 dimension array with some data transformed, you need to nest your map functions. This will map first over the rows (outer), then the columns (inner). The results of the inner maps will be collected into the outer map and you'll be left with a 2 dimensional array with your new values, all without modifying the original array.

Related

GoogleScript - convert arrays of different lengths into arrays of the same length

To be able to use setValues() instead of setValue on a high number of rows, I would like to know how can I convert all my arrays into arrays of the same length.
During a map function, I create one giant array that looks like this :
const myArray = [[Monday, Tuesday],[Monday,Tuesday,Wednesday],[Friday],[Monday,Friday],[Tuesday,Wednesday,Friday]] // And so on.
At the moment I use a setValue for each item of the array. The next step would be simply to use setValues(), and append an array but the problem is they are all of different lengths.
result.forEach(function(_,index){
currentSheet.getRange(1+index,5).setValue(result[index]);
});
That is going to do that for 600 lines and I will do it several times with other functions. I can live with it, but it seems like a waste. Is there a way to make the arrays homogenous (all arrays would be have a length of 3 elements, one or two being empty for example) an use one single setValues() instead ?
EDIT : the original map function to create the first array was requested. Here it is :
(Basically what it does is : it runs a map through a first array, look at the first element and go find in the source all the elements that have the same key and return the 9th and 10th elements of that array)
const result = UniquesDatas.map(uniqueRow =>
SourceDatas
.filter(row => row[0] === uniqueRow[0])
.map(row => [row[9]+" "+row[10]])
);
Thank you in advance,
Cedric
You can concat an array of empty elements of the remaining length.
const myArray = [['Monday', 'Tuesday'],['Monday','Tuesday','Wednesday'],['Friday'],['Monday','Friday'],['Tuesday','Wednesday','Friday']]
const res = myArray.map(x => x.concat(Array(3 - x.length)));
console.log(res);
As suggested by Kinglish, to get the length of the inner array with the most elements, use Math.max(...myArray.map(x=>x.length)), which will work for the more general case.

How to Push Rows with Unique Values of Array into Another Array without Changing Order in Javascript

I am trying to figure out how to push rows of array values from a multidimensional array into another array that has rows of unique values that don't repeat.
For example, if I have an array:
[['A','B','C','D'],['E','F','F','G'],['1','2','3','4']]
I want to push the rows into another array so that it contains only the rows with values that don't repeat so I will have:
[['A','B','C','D'],['1','2','3','4']]
This is a simple example. My array is much larger. I am trying to do this using javascript for arrays with thousands of rows.
You can use .filter() with a Set. The Set will remove any duplicate items, so, if the size of the Set equals the size of the row then no elements were removed, which means you can keep the array in the resulting array by returning true from your .filter() callback.
See example below:
const arr = [['A','B','C','D'],['E','F','F','G'],['1','2','3','4']];
const res = arr.filter(row => new Set(row).size === row.length);
console.log(res);
If you must use .push(), this can be done using a for...of loop and only pushing the row into your new array when all values are unique:
const arr = [['A','B','C','D'],['E','F','F','G'],['1','2','3','4']];
const newArr = [];
for(const row of arr) {
if(new Set(row).size === row.length)
newArr.push(row);
}
console.log(newArr);

How to use reduce to iterate an array

I have been doing research on the benefits of using reduce over map. Mainly the benefit is that reduce has better performance time.
My question is how would i be able to use reduce to iterate over an array as if i would for the map function ?
An example
The following code combines the fruits to one string. How would i be able to iterate over this array using the reduce function ?
const fruits = ['pears', 'plums', 'grapes', 'apples']
console.log(fruits.reduce( (acc, fruit) => acc.concat(fruit)))
// "pearsplumsgrapesapples"
You'll sacrifice code legibility for a millisecond of difference but here it is:
['pears', 'plums', 'grapes', 'apples'].reduce(function (acc, currentFruit) {
// Your code here
acc.push(currentFruit);
return acc;
}, []);
You'll have to push your current value to a an array because the reduce method objective is to reduce the provided data to a single value.
At the end of the day, map is just better, simpler and you won't be able to notice the time difference.
The reduce function indeed iterates over the array, because it's meant to reduce all the array items to a single value by applying a function.
The map function iterates on the array too, in order to project the array elements to a value calculated by applying a provided function.
The difference between the two functions is that they are iterating over the array for a different purpose. Reduce is used to compute single value, map is used to project each array item to a new value.
In both cases you can't say anything about the computational complexity because you are passing a callback and you don't know what that callback is going to do. So the computational complexity depends on the callback function.
Take a look at this paper about reduce: https://hackernoon.com/javascript-array-reduce-50403c421968
You could pass an empty array as the reduce function accumulators initial value, then within the body of your reduce function you can append to the acc which will now be an array and execute conditional logic.
map is simple. It calls the function on each element of the input array, and returns a new array containing the corresponding function results.
result = array.map(f)
is equivalent to
result = [f(array[0], 0, array), f(array[1], 1, array), f(array[2], 2, array), ...]
You use reduce if you want to combine the results of each iteration in a custom way, to produce one result. The function takes two arguments -- the first is the return value of the previous iteration, and the second is the current element from the iteration.
result = array.reduce(f, init)
is equivalent to
temp1 = f(init, array[0], 0, array);
temp2 = f(temp1, array[1], 1, array);
temp3 = f(temp2, array[2], 2, array);
...
result = f(tempN, array[N], N, array);
If you don't provide an initial value argument, the first line becomes
temp1 = array[0];
and the rest is the same.
If you don't actually need a new result, you just want to execute some code on each array element, you use forEach(). It's like map, but it doesn't collect the results. If you want to log each array element on a new line, you would do:
array.forEach(el => console.log(el));

How to create a 1d and a 2d array and how to initialize an array with a particular array size in Protractor?

I'm new to protractor. I want to create a 1d array and a 2d array and want to initialize the array by passing no.of rows and no.of columns like below
I'm mentioning Java array as an example
String[][] data=new String[2][3];
I want to know how to initialize the array in protractor like in Java. And it's better and knowledge-sharing for me by explaining the initialization of a 1d array also.
JavaScript is not a strongly typed language like Java, so arrays don't need to be initialized. However we can still initialize an array if we would like.
To create a 1d array use new Array:
let array = new Array(10) // An array with 10 items
You can then fill the array with a value using fill:
let array = new Array(10).fill('dog') // An array with 10 items with a value of dog
Taking the above, we can then initialize a 2d array by creating a new array with a set length and fill it with arrays. Since fill will take a value an use it once, we cannot pass new Array() to fill. We will need to map the first array and change it's value to an array. Map takes a function so we just return a new array from the map and it will replace the original values with an array.
The result looks like this:
function initArray(rows, cols, filler = null) {
return [...new Array(rows)].map(() => new Array(cols).fill(filler))
}
// create an array with all nulls
let arr = initArray(2, 3)
console.log(JSON.stringify(arr))
// Change a value in the array
arr[0][1] = 'dog'
console.log(JSON.stringify(arr))
// Create an array with a filler
console.log(JSON.stringify(initArray(5, 2, 'dog')))
Note: Remember that since this is javascript and not java, the size of the array is not set in stone, and it is 100% possible to push more items onto the array making it larger than the specified size without error and javascript will not complain.
First of all, If you are using protractor to automate your website then you must be using some language like 'java/ javascript / typescript', so its better that you search for "how to declare and initialize array in any of these languages.So for me im using typescript in my project so here it is :
var alphas:string[];
alphas = ["1","2","3","4"];
console.log(alphas[0]);
console.log(alphas[1]);`
https://www.tutorialspoint.com/typescript/typescript_arrays.htm

Javascript slice isn't giving me correct array length values

Why does it say length 1 instead of 4?
The following is what I'm trying to push and slice. I try and append items.image_urls and slice them into 5 each.
items.image_urls is my dictionary array.
var final_push = []
final_push.push(items.image_urls.splice(0,5))
console.log(final_push.length)## gives me 1...?
var index = 0
final_push.forEach(function(results){
index++ ##this gives me one. I would need 1,2,3,4,5,1,2,3,4,5. Somehting along that.
}
items.image_urls looks like this:
It's an iteration of arrays with image urls.
In your example items.image_urls.splice(0,5) returns an array of items removed from items.image_urls. When you call final_push.push(items.image_urls.splice(0,5));, this whole array is pushed as one item to the final_push array, so it now looks like [["url1", "url2", "url3", "url4", "url5"]] (2-dimensional array). You can access this whole array by calling final_push[some_index].
But what you want instead is to add every element of items.image_urls.splice(0,5) to the final_push. You can use a spread operator to achieve this:
final_push.push(...items.image_urls.splice(0,5));
Spread syntax allows an iterable such as an array expression or string
to be expanded in places where zero or more arguments (for function
calls) or elements (for array literals) are expected
This is exactly our case, because push() expects one or more arguments:
arr.push(element1[, ...[, elementN]])
And here is an example:
let items = {
image_urls: ["url1", "url2", "url3", "url4", "url5", "url6", "url7", "url8", "url9", "url10"]
};
let final_push = [];
final_push.push(...items.image_urls.splice(0,5));
console.log(final_push.length);
console.log(JSON.stringify(final_push));
console.log(JSON.stringify(items.image_urls));
Note: do not confuse Array.prototype.slice() with Array.prototype.splice() - the first one returns a shallow copy of a portion of an array into a new array object while the second changes the contents of an array by removing existing elements and/or adding new elements and returns an array containing the deleted elements.
That seems to be a nested array. So if you would access index 0, and then work on that array like below it will probably work:
console.log(final_push[0].length); //should print 4
The author is mixing up splice and slice. Probably a typo :)
You start at the beginning (0) and then delete 5 items.

Categories

Resources