Reputation: 153
I am trying to get the index of the maximum and minimum element of a specific column in the matrix. Now I am doing as follows using ES6 and Spread syntax:
a = [
[22,23],
[74,1],
[21,33],
[32,84],
[11,31],
[1,49],
[7,8],
[11,11],
[99,68],
[52,20]
];
const minValue = (arr, n) => Math.min(...arr.map(x => x[n])); //n - column index
const maxValue = (arr, n) => Math.max(...arr.map(x => x[n]));
const minValueIndex = (arr, n) => arr.map(x => x[n]).indexOf(minValue(arr, n));
const maxValueIndex = (arr, n) => arr.map(x => x[n]).indexOf(maxValue(arr, n));
console.log(minValue(a, 0));
console.log(maxValue(a, 0));
console.log(minValueIndex(a, 0));
console.log(maxValueIndex(a, 0));
But at the same time too many comparisons are made, I do not think that this is the best way to complete this task. I would be glad to see faster implementations using the ES6 standard or without it.
Upvotes: 2
Views: 559
Reputation: 6390
You are almost there and you are just concern about the performance right? So for improving the performance of your program, you can use a nice technique called Memoization
Memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again
const arr = [[22,23], [74,1], [21,33], [32,84], [11,31], [1,49], [7,8], [11,11], [99,68], [52,20]];
/**
* Here I create the momoized function which cache the
* column and if we want to get the same column then it
* simply return the previously cached column array
* otherwise, it get the column and cache it for future
* and return it.
*/
const memoized = () => {
const cache = {};
return (arr, index) => {
if (index in cache) {
return cache[index];
} else {
const col = arr.map(item => (item[index]));
cache[index] = col;
return col;
}
}
}
/**
* As memoized is a higher order function so it returns
* another function which will be executed by calling
* this getColumn function reference.
*/
const getColumn = memoized();
const getMinValue = (arr, col) => Math.min(...getColumn(arr, col));
const getMaxValue = (arr, col) => Math.max(...getColumn(arr, col));
const minValueIndex = (arr, col) => getColumn(arr, col).indexOf(getMinValue(arr, col));
const maxValueIndex = (arr, col) => getColumn(arr, col).indexOf(getMaxValue(arr, col));
console.log('minValue: ', getMinValue(arr, 0)); // Calculated
console.log('maxValue: ',getMaxValue(arr, 0)); // Cached
console.log('minValueIndex: ', minValueIndex(arr, 0)); // Cached
console.log('maxValueIndex: ', maxValueIndex(arr, 0)); // Cached
.as-console-wrapper {min-height: 100% !important; top: 0;}
Upvotes: 1
Reputation: 154
Will this help?
let a = [
[22, 23],
[74, 1],
[21, 33],
[32, 84],
[11, 31],
[1, 49],
[7, 8],
[11, 11],
[99, 68],
[52, 20]
];
let max = 0,
min = 0,
minIndex = 0,
maxIndex = 0;
const findValue = (array, col) => {
array.map((matrix) => {
(matrix[col] > max) ? max = matrix[col]: null;
(min == 0) ? min = max: null;
(matrix[col] < min) ? min = matrix[col]: null;
})
}
const findIndex = (array, col, min, max) => {
minIndex = array.map(data => data[col]).indexOf(min);
maxIndex = array.map(data => data[col]).indexOf(max);
}
findValue(a, 0)
findIndex(a, 0, min, max);
console.log(min, max, minIndex, maxIndex);
Upvotes: 1
Reputation: 8611
A simple solution would be to loop over the array and store the min/max values in a temporary variable.
function minMax (arr, n) {
let min=Infinity, max=0;
for (const _arr of arr) {
const x = _arr[n];
if (x < min) min = x;
if (x > max) max = x;
}
return [min, max];
}
function minMaxIndex (arr, n) {
let min=Infinity, max=0, minIndex, maxIndex;
for (let i=0; i < arr.length; i++) {
const x = arr[i][n];
if (x < min) {
min = x;
minIndex = i;
}
if (x > max) {
max = x;
maxIndex = i;
}
}
return [minIndex, maxIndex];
}
console.log (minMax(a, 0))
console.log (minMaxIndex(a, 0))
<script>
a = [
[22,23],
[74,1],
[21,33],
[32,84],
[11,31],
[1,49],
[7,8],
[11,11],
[99,68],
[52,20]
];
</script>
Upvotes: 1