Why is this attempt to retrieve the minimum number of an array not working? - javascript

Max should be = 9.99, and min should be = 6.88
let arr = [["2019","00","01", 9.99], ["2018","00","01", 9.32], ["2017","00","01", 6.88]]
let max = Math.max(Number(...arr.map((o) => { return o[3] }))); //9.99
let min = Math.min(Number(...arr.map((o) => { return o[3] }))); //9.99
console.log(min);
console.log(max);

let arr = [["2019","00","01", 9.99], ["2018","00","01", 9.32], ["2017","00","01", 6.88]];
let max = Math.max(...arr.map((o) => { return o[3] })); //9.99
let min = Math.min(...arr.map((o) => { return o[3] })); //6.88
console.log({
max , min
})

Earlier, you had put Number around the mapped array. This converts the array to a number. However, you only wanted the individual elements to be numbers so move it inside the map function.
let arr = [
["2019","00","01", 9.99],
["2018","00","01", 9.32],
["2017","00","01", 6.88]
];
let max = Math.max(...arr.map((o) => { return Number(o[3]) })); //9.99
let min = Math.min(...arr.map((o) => { return Number(o[3]) })); //6.88
// this can be rewritten like so:
// Math.min(...arr.map((o) => Number(o[3])));
//
// https://www.w3schools.com/js/js_arrow_function.asp
console.log(max);
console.log(min);
So,
before:
let min = Math.min(Number(...arr.map((o) => { return o[3] }))); //9.99
after
let min = Math.min(...arr.map((o) => { return Number(o[3]) })); //6.88

Related

How to return the element of an array containing the max value (index 1) (Javascript)?

Given the array below, how can I return the element containing the max number?
let ar = [["finalOrderData",1],["finalFabricData",3],["finalDecorationData",3],["finalHtData",3]]
Expected Result
let ar = ["finalFabricData",3]
This is the function I'm trying with, but it only returns the number itself:
function getMaxOf2DIndex(arr, idx) {
return Math.max.apply(null, arr.map(function (e) { return e[idx] }))
}
Appreciate any help!
Use Array.sort():
let ar = [['finalOrderData', 1], ['finalFabricData', 3], ['finalDecorationData', 3], ['finalHtData', 3]];
let res = ar.sort((a, b) => b[1] - a[1])[0];
console.log(res);
Note that this doesn't handle the alphabetical order of the word.
You can use the Array.reduce function
let ar = [["finalOrderData",1],["finalFabricData",3],["finalDecorationData",3],["finalHtData",3]]
let result = ar.reduce((acc,cur) => !acc || cur[1] > acc[1] ? cur : acc, undefined);
console.log(result);
function getMaxOf2DIndex(arr, idx) {
let maxItem = arr[0];
arr.forEach((item, i) => {
if(item[idx] >= maxItem[idx])
maxItem = item;
});
return maxItem;
}
I think the most straightforward way:
let ar = [["finalOrderData",1],["finalFabricData",3],["finalDecorationData",3],["finalHtData",3]]
var maxNumber = ar[0]
ar.forEach((element) => maxNumber = element[1] > maxNumber[1] ? element : maxNumber)
or the same written more verbosely:
let ar = [["finalOrderData",1],["finalFabricData",3],["finalDecorationData",3],["finalHtData",3]]
var maxNumber = ar[0]
for (element of ar) {
let number = element[1]
if (number > maxNumber[1])
maxNumber = number
}
Here are 2 examples:
const ar = [
["finalOrderData",1],
["finalFabricData",3],
["finalDecorationData",3],
["finalHtData",3]
]
// the 1st result of the biggest value:
const output1 = ar.sort((A,B) => B[1] - A[1])[0]
console.log(output1)
// output: ["finalFabricData",3]
// the last result of the biggest value:
const output2 = ar.sort((A,B) => B[1] <= A[1] ? -1 : 1)[0]
console.log(output2)
// output: ["finalHtData",3]
one more Solution using Array.reduce:
ar.reduce((res, val) => Math.max(res[1],val[1]) === res[1] ? res : val );
trick here is to check with already calculated result.

sample array n^2 times without the same number occurring twice in a row and not repeating every n

I'm trying to write a function that has the arguments of the array to sample arr and the number of samples, size (which is sqaured) and randomly samples from the original array:
arr = [1,2,3,4]
single_number = (x) => {
return x[Math.floor(Math.random()*x.length)];
}
randomize = (arr, size) => {
return Array(size*size).fill().map(x => single_number(arr))
}
randomize(arr, 5)
I want to add the additional requirements to my randomize function:
no number shows up twice in a row
make sure every sizeth item is not the same as the one before it
For example
randomize([1,2,3,4], 2)
[2,4,3,2,4,1,1,2,2,1,4,1,1,1,3,1,1,4,4,1,3,3,2,2,3]
CASE (1)
[
2,4,3,2,4,
2,1,
2,2, // illegal!
1,4,
1,1,1, // illegal!
3,
1,1, // illegal!
4,4, // illegal!
1,
3,3, // illegal!
2,2, // illegal!
3
]
CASE (2)
[
2,4,3,2,4, [0] === 2
2,1,2,2,1, [5] === 2 // illegal!
4,1,1,1,3,
1,1,4,4,1,
3,3,2,2,3
]
I'm trying to use functional programming and avoid a for loop if possible since I think I can do this with a nested for loop?
Well, this isn't as pretty as one would hope, but I think it accomplishes the objective: Iterate size^2 times and choose random elements from the input, taking care to exclude the last value and last nth value chosen...
const randomize = (array, size) => {
const rand = () => Math.floor(Math.random() * array.length);
const randExcept = exclude => {
let v = array[rand()];
while (exclude.includes(v)) v = array[rand()];
return v;
}
const indexes = Array.from(Array(size*size).keys());
let lastV = null, nthV = null;
return indexes.map(i => {
let exclude = nthV!==null && i%size===1 ? [lastV, nthV] : [lastV];
let v = randExcept(exclude);
lastV = v;
if (i%size===1) nthV = v;
return v;
})
}
console.log( JSON.stringify(randomize([1,2,3,4], 2)) )
This defines nth values by the count into the array, so for size===2, the constraint is that every second element (indexes 1,3,5...) can't be equal to the prior second element.
I'd probably do something like this:
const values = [1,2,3,4]
function randomize(values, size) {
let prev;
let prevNth;
return Array(size*size).fill().map( randomNumber );
function randomNumber(_,i) {
let value, ok;
do {
value = values[ Math.floor( Math.random() * values.length ) ];
ok = value != prev;
if ( i % size === 0) {
ok = ok && value != prevNth;
prevNth = value;
}
prev = value;
} while (!ok);
return value;
}
}
arr = randomize(values, 5)
console.log(JSON.stringify(arr));
Or this, using a generator to generate the appropriately sized stream of randomness:
const values = [1,2,3,4];
const arr1 = Array.from( randomValues(5,values) );
console.log(JSON.stringify(arr1));
function *randomValues(n, values) {
const limit = n*n;
let prev, prevNth;
for ( let i = 0 ; i < limit ; ++i ) {
const isNthValue = i % n === 0;
const value = randomValue( values, prev, isNthValue ? prevNth : undefined );
yield value;
prev = value;
prevNth = isNthValue ? value : prevNth;
}
}
function randomValue(values, test1, test2 ) {
let value;
do {
value = values[ Math.floor( Math.random() * values.length ) ];
} while (value === test1 || value === test2 );
return value;
}

Count all values in object where X is the first key letter

I would like to count all values where a letter appears first and return the letter with atleast half of all values in my object so for example I assuming I have an object like this
const sample = { "A,B,C": 4, "B,C,A": 3, "C,B,A": 2, "A,C,B": 2 };
I would return A because if you count all the values where A appears first you would get 6 (4+2)
This is what I currently have:
for (let votes of Object.values(sample)) {
sum += votes
}
stretchWin = Math.round(sum / 2)
winner = Object.entries(sample)
.filter(([, val]) => val >= stretchWin)
.map(([keys]) => keys)
With this I am getting an empty array because I am not counting all the values assigned to A
Iterate over the whole sample first to get a sum of the values by the first letter first, then iterate over that new object to identify which values match the target of half the total.
const sample = {
"A,B,C": 4,
"B,C,A": 3,
"C,B,A": 2,
"A,C,B": 2
};
const sumByChar = {};
for (const [key, value] of Object.entries(sample)) {
const char = key[0];
sumByChar[char] = (sumByChar[char] ?? 0) + value;
}
let sum = 0;
for (let votes of Object.values(sample)) {
sum += votes
}
const targetSum = Math.round(sum / 2);
const winners = Object.entries(sumByChar)
.filter(([, val]) => val >= targetSum)
.map(([key]) => key);
console.log(winners);
I'm not completely sure what you mean what the outcome should be. If I understand correctly you want something like this??
const sample = { "A,B,C": 4, "B,C,A": 3, "C,B,A": 2, "A,C,B": 2 };
const totalSum = Object.values(sample).reduce(
(previousValue, currentValue) => previousValue + currentValue,
0
);
const stretchWin = Math.round(totalSum / 2);
const winner = Object.entries(sample)
.filter(([key, value]) => {
const isFirstLetterA = key.startsWith("A");
return isFirstLetterA || value >= stretchWin;
})
.map(([key, value]) => value)
.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
console.log(winner);

create array of object from array of strings

I am trying to solve one issue in my code, so if anyone can help me here?
I have some values added below, So i have one array of string values, which has mac addresses and min & max which is constant values. I am trying to map over macValue and trying to create array of object as given sample below, but unfortunately getting some error there. If anyone can help me out here.
please check here i am trying to dynamically add property inside map.
let macValue = ["MO-CK-DR-01","02","03"]
let min = true
let max = true
// code i have tried
var print = macValue.map((item, i) => {
(item['macAddress'] = item), (item.minimum = min), (item.maximum = max);
return item;
});
trying to create array of object like this
[
{
macAddress: value, //01
mimimum: min,
maximum: max,
},
{
macvalue: value, // 02
mimimum: min,
maximum: max,
},
]
but didn't work and getting this error
As simple as:
let macValue = ["MO-CK-DR-01","02","03"]
let min = true
let max = true
const obj = macValue.map((value) => ({
macvalue: value,
minimum: min,
maximum: max,
}))
let macValue = ['MO-CK-DR-01', '02', '03'];
let min = true;
let max = true;
const result = macValue.map((value) => ({
macValue: value,
minimum: min,
maximum: max
}));
console.log(result);
let macValue = ['MO-CK-DR-01', '02', '03'];
let min = true;
let max = true;
const output = macValue.map(value => ({
macValue: value,
minimum: min,
maximum: max
}));
console.log(output);
As you mentioned, the properties are dynamic, I have used string properties. This should work -
let macValue = ['MO-CK-DR-01', '02', '03'];
let min = true;
let max = true;
const result = macValue.map((value) => ({
'macAddress': value,
'minimum': min,
'maximum': max
}));
console.log(result);

How could I find intersections in a string array with a variable number of elements?

I have a function that receives an array composed of numerical, comma separated strings as input, then finds the intersectional numbers in those strings and returns a string of similarly comma separated numbers, with no spaces, containing those intersections. If there are no intersections between the two elements, the function will return false.
What I want is to optimize the function so that it can work with a string array that may have more than just two elements. Is that possible? If so, could I have some sort of guideline of where to start looking for answers?
Currently, this is what I have.
function LocateIntersection(strArr) {
let arrHalf1 = strArr[0].split(", ");
let arrHalf2 = strArr[1].split(", ");
let interArr = arrHalf1.filter(value => arrHalf2.includes(value));
let result = interArr.join();
if (result) {
return result;
} else {
return false;
}
}
My answer is a little flawed, but it should meet your requirements
function LocateIntersection(strArr) {
const AllArrHalf = strArr.map((value) => value.split(', ')).sort((a, b) => b.length - a.length);
const lastArrHalf = AllArrHalf[AllArrHalf.length - 1];
let interArr = [];
AllArrHalf.forEach((value, index) => {
if (index !== AllArrHalf.length - 1) {
interArr.push(lastArrHalf.filter(value1 => value.includes(value1)))
}
})
if (interArr.length > 1) {
let result = interArr.map(value => value.join(', '));
LocateIntersection(result);
} else if (interArr.length === 1) {
result = interArr.join();
console.log(result);
}
}
LocateIntersection(['a, b, c', 'a, b', 'a, b'])
You can try this.
const intersection = (arr1, arr2) => {
return arr2.filter(element => arr1.includes(element));
}
const getIntersection = (stringArray, prevResult) => {
const array1 = prevResult || stringArray[0].split(', ');
const array2 = stringArray.shift().split(', ');
const result = intersection(array1, array2);
console.log(`result : `, result)
if(result.length > 0 && stringArray.length > 0) {
return getIntersection(stringArray, result);
}
return result;
}
const input = ['1, 2','1, 3, 3, 3','123, 222','1, 1, 1','1','3, 2, 3, 1'];
const result = getIntersection(input);
console.log('final Result:',result);

Categories