Do anyone understand this reduce method problem Im having? - javascript

Do anyone understand why console.log(posArr) is printing [1,2,3] and not [0,1,2]. Im trying to push to nOfPos all the index positions of my array :)
function combinations(x) {
let arr = x.toString().split('');
console.log(arr)
let nOfPos = [];
let posArr = arr.map(x => nOfPos.push(arr.indexOf(arr[x])));
let mult = posArr.reduce((acum, item) => acum * item);
console.log(posArr);
console.log(mult);
}
combinations(123)

The problem is due to two errors in your code. Firstly push() returns the new length of the array, so that's why the mapped output contains the incremental 1,2,3....
Secondly, you need to search for x within arr, so you only need to pass x to indexOf().
With those issues corrected the code works:
function combinations(x) {
let arr = x.toString().split('');
let posArr = arr.map(x => arr.indexOf(x));
let mult = posArr.reduce((acum, item) => acum * item);
console.log(posArr);
console.log(mult);
}
combinations(123)
That being said, the purpose of posArr is a little redundant; it will always be an array of incremental values, up to the length of the string -1.
In addition, mult is redundant too as it will always be 0, as you are multiplying by 0.

You could use a 'for in' loop to get the array indexes.
let posArr = [];
for (ix in arr) {
posArr.push(ix)
}

Related

How can I find a specific value inside a nested array?

Question: I have this array that have a nested array that I want to loop to find a specific value.
arr = [['123456','234567'], ['345678']];
specificValue = '123456';
The output that I want is to find out if there's a value same with specificvalue and return this value?
I tried
arr.filter(id => id === specificValue);
Thanks for the help
Let's keep going with your attempt.
The problem is your array is nested so array.filter will not work
Use array.flat with array.filter:
let arr = [['123456','234567'], ['345678']];
let specificValue = '123456';
console.log(arr.flat().filter(i=>i==specificValue))
Try this code
const arr = [['123456','234567'], ['345678']];
const result = arr.flat(Infinity).find(val => val === "123456");
console.log(result);
You can learn more about array.flat() method here
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
Since flat() takes a depth as an argument, to be able to search in an indefinite number of nested arrays you could try good old recursion:
const findRecursive = (array, target) => {
for (let i = 0; i < array.length; i++) {
if (array[i] === target) {
return array[i];
} else if (Array.isArray(array[i])) {
return findRecursive(array[i], target);
}
}
}
console.log(findRecursive(arr, specificValue));
EDIT: Abdelrhman Mohamed has corrected me, you can specify an indefinite amount of nested arrays using array.flat(Infinity)

Javascript Sort Array without change the index

I have a array like this:
arr[1] = 100
arr[10] = 20
arr[20] = 10
When I iterate the array, I got:
arr[1]:100 arr[10]:20 arr[20]:10
Currently, the array is sorted by the index. How can I sort it by the value but KEEP the original index.
What I want is:
arr[20]:10 arr[10]:20 arr[1]:100
I checked other posts but didn't find a solution to this specific issue. I am not sure javascript supports this. Can I get some help?
Thanks!
When we speak of a sorted array in JavaScript, we mean that an iteration over the array by increasing index produces the values in sorted order.
Your requirements would actually require an array with pairs of ("index", value).
Here is how that works:
let arr = [];
arr[1] = 100;
arr[10] = 20;
arr[20] = 10;
let result = Object.entries(arr).sort((a, b) => a[1]-b[1])
.map(([k, v]) => [+k, v]); // optional conversion
console.log(result);

How do I get multiple index on an Array

I am trying to get multiple index positions on an Array for a Boolean value.
I have tried applying a loop using while and for to iterate more then one index position with no success so far.
Here is my code:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
let checker = (arr1,arr2) => {
let falsy = arr1.every(num => arr2.includes(num)) == false ?
arr1.map(falsy => arr2.includes(falsy)) : "tba";
//the block below is the frustrated attempt:
let i = falsy.indexOf(false);
while(i>=0){
return falsy.findIndex(ih => ih == false)
}
}
console.log(checker(jo,ji))
I would like to get the index where false occurs stored in a variable that has iterated over all array so I can use this variable to return just the false values on falsy like this:
return falsy[i] = [4,5]
Then after that I will add more to the first if statement to check both arr1 x arr2 or arr2 x arr1
Thanks in advance!
It looks like you're attempting to get the difference between two arrays. This is a fairly comment use-case for Sets. In this case, your code would look like this:
let jo = [1,2,3,4,5]
let ji = [1,2,3]
const checker = (arr1, arr2) => {
return new Set(arr1.filter(x => !new Set(arr2).has(x)))
}
console.log(checker(jo, ji)); // {4, 5}
If you wanted to get the indexes of the differences, you would need to apply a map to the result of the new Set like so:
const checker = (arr1, arr2) => {
const difference = new Set(arr1.filter(x => !new Set(arr2).has(x)));
return Array.from(difference).map(value => arr1.indexOf(v));
}

What is the javascript equivalent of numpy argsort?

I want to sort the imgUrl array by click count. I have two arrays.
clickCount = [5,2,4,3,1]
imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg']
In numpy it is easy. I use order = np.argsort(clickCount) then I create another array newArray = [imgUrl[i] for i in order].
How do I achieve the same effect in javascript (preferably vanilla)?
You can use a Schwartzian transform also known as Decorate-Sort-Undecorate (DSU) in python.
DSU:
Decorate - Use Array#Map to enrich each item in the array with the needed sort data
Sort - sort using the added data
Undecorate - extract the sorted data using Array#map again
Demo:
const dsu = (arr1, arr2) => arr1
.map((item, index) => [arr2[index], item]) // add the args to sort by
.sort(([arg1], [arg2]) => arg2 - arg1) // sort by the args
.map(([, item]) => item); // extract the sorted items
const clickCount = [5,2,4,3,1];
const imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg'];
const result = dsu(imgUrl, clickCount);
console.log(result);
thanks to dankal444 for the refactor to the function
For completeness, here's my solution to the actual answer (providing argsort function), by expanding on Ori's answer with DSU.
Since sort is by default taking the first element, so implementing it as DSU is merely adding an index, sorting it, then taking the indices.
let decor = (v, i) => [v, i]; // set index to value
let undecor = a => a[1]; // leave only index
let argsort = arr => arr.map(decor).sort().map(undecor);
clickCount = [5, 2, 4, 3, 1]
imgUrl = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg']
order = argsort(clickCount);
newArray = order.map(i => imgUrl[i])
console.log(newArray);
Functional approach (like #Ori Drori's code) is always a charm to watch, but in this case, you only need to re-arrange an array's items. I believe that there is a simpler way to go and is a much easier code to read.
const clickCount = [5,2,4,3,1];
const imgUrl = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg'];
sortByArrayRefOrder = (data, orderRefArr) => {
let orderedArr = [], i=0;
orderRefArr.map( o => { orderedArr[o-1] = data[i++]});
return orderedArr.reverse();
}
console.log ( sortByArrayRefOrder(imgUrl, clickCount) );

Using Map-Reduce to Return A Modified Array of Strings

I am learning map & reduce, but am having a hard time understanding how to utilize these methods to tackle problems.
For example,
Create a function that takes a number and returns an array of strings containing the number cut off at each digit.
420 should return ["4", "42", "420"]
My old Approach:
function createArrayOfTiers(num) {
var numArr = num.toString().split('');
var output = [];
for(var i = numArr.length-1; i>=0; i--) {
output.unshift(numArr.join('');
numArr.pop();
}
return output;
}
Attempt to use map-reduce combination:
function createArrayOfTiers(num) {
var numArr = num.toString().split('');
return numArr.map(function(element) {
var newElement = numArr.reduce(function(acc, val) {
return acc + val;
});
numArr.splice(element, 1);
return newElement;
});
}
You have used two loops, but apparently it can be done just with one.
function n(num) {
let res = (""+num).split('').map((_,i) => (""+num).slice(0, i+1));
return res;
}
console.log(n(420));
console.log(n(13579));
One-liner.
const n = num => (""+num).split('').map((_,i) => (""+num).slice(0, i+1));
console.log(n(420));
console.log(n(13579));
As others noted, that this problem doesn't seem to be the best use case of the map and reduce functions.
map function provides the element, index and array information in the parameters. Making use of these you can iterate on the elements you need to apply the reduce function.
Statement var arrayToIterate = arr.slice(0,i+1); helps to achieve the above mentioned array to iterate.
Complete Code:
function createArrayOfTiers(num) {
var numArr = num.toString().split('');
return numArr.map(function(element, i, arr) {
var arrayToIterate = arr.slice(0,i+1);
var newElement = arrayToIterate.reduce(function(acc, val) {
return acc + val;
},"");
return newElement;
});
}
var result = createArrayOfTiers(420);
console.log(result);
I don't think these are good uses-cases of map or reduce, but here goes :
var numArr = [4,2,0];
var result = numArr.map(e => numArr.join('')) // now ["420", "420", "420"]
.map((arr, i) => arr.substring(0, i+1)) // now ["4", "42", "420"]
console.log(result);
We first replace every element of the array by the whole (unmodified) array joined into a string, then substring each of these strings based on their position in the outer array.
There's a reduction hidden in there, although not using reduce : join reduces [4, 2, 0] to "420".
I am learning map & reduce, but am having a hard time understanding how to utilize these methods to tackle problems.
Mapping associates to each value of the source array a new value provided by a mapping function : if you have an [x, y, z] array, a mapping function f(x)=x+1, the result of mapping the array with the function will be [x+1, y+1, z+1].
I believe reduction was meant to "reduce" an array to a primitive type, although I might be mistaken. If you have an [x, y, z] array and reduce it with the addition operation, the result will be x+y+z.

Categories

Resources