Related
It's a bit of a tricky situation I'm in, but I have an array like this:
const nums = [32, -3, 62, 8, 121, -231, 62, 13];
and need to replace them by their corresponding ascending index. The above example should yield:
[4, 1, 5, 2, 7, 0, 6, 3]
The solution I've come up with is this: TS Playground
const nums = [32, -3, 62, 8, 121, -231, 62, 13];
const numsCopy = nums.map(e => e);
// Basic sorting
for (let i = 0; i < numsCopy.length; i++) {
for (let j = 0; j < numsCopy.length; j++) {
if (numsCopy[i] < numsCopy[j]) {
let t = numsCopy[j];
numsCopy[j] = numsCopy[i];
numsCopy[i] = t;
}
}
}
for (let i = 0; i < numsCopy.length; i++) {
let sortedValue = numsCopy[i];
nums[nums.indexOf(sortedValue)] = i;
}
Problems arise however when I change nums to include a value nums.length > n >= 0. The call nums.indexOf(...) may return a faulty result, as it may have already sorted an index, even though it exists somewhere in the array.
If you replace nums with these values, -231 will have an index of 2 for some reason...
const nums = [32, -3, 62, 7, 121, -231, 62, 13, 0];
> [5, 1, 6, 3, 8, 2, 7, 4, 0]
Is there a better approach to this problem, or a fix to my solution?
You could sort the indices by the value and create a new array with index values a sorted positions.
to get the wanted result call the sorting function again and you get the indices sorted by the index order.
const
sort = array => [...array.keys()].sort((a, b) => array[a] - array[b]),
fn = array => sort(sort(array));
console.log(...fn([32, -3, 62, 8, 121, -231, 62, 13])); // 4 1 5 2 7 0 6 3
console.log(...fn([-1, 3, 1, 0, 2, 9, -2, 7])); // 1 5 3 2 4 7 0 6
Copy the array, sort its values, get indexOf, and null the value in the sorted copy:
const sortIndicesByValue = array => {
const sorted = [...array].sort((a, b) => a - b);
return array.map(e => {
const i = sorted.indexOf(e);
sorted[i] = null;
return i;
})
}
console.log(...sortIndicesByValue([32, -3, 62, 8, 121, -231, 62, 13]));
console.log(...sortIndicesByValue([-1, 3, 0, 0, 2, 9, -2, 7]));
I have to create two 10-elements arrays with random values from 1 to 20 and write a program that prints the largest value that occurs simultaneously in both arrays.
I created two tabs like below. The program should prints the largest value that occurs simultaneously in both arrays. Here it should be 11. I know just how to catch the max value from the array. I appreciate help.
<script>
var max = 0;
var tab = [1, 2, 5, 8, 9, 11, 15, 16, 17, 20];
var tab2 = [3, 4, 6, 7, 10, 11, 12, 13, 14, 18];
for (var i = 0; i < tab.length; i++) {
if (max <= tab[i]) {
max = tab[i];
}
}
console.log(max);
</script>
to find the largest value use nested loops to compare each element of both arrays as follow
var tab = [1, 2, 5, 8, 9, 11, 15, 16, 17, 20];
var tab2 = [3, 4, 6, 7, 10, 11, 12, 13, 14, 18];
var max = 0;
for (var i = 0; i < tab.length; i++) {
for (var j = 0; j < tab2.length; j++) {
if (tab[i] === tab2[j] && tab[i] > max) {
max = tab[i];
}
}
}
console.log(max);
I'd do this:
// const {intersection,max} require('lodash/fp'}
const { intersection, max } = _;
const tab = [1, 2, 5, 8, 9, 11, 15, 16, 17, 20];
const tab2 = [3, 4, 6, 7, 10, 11, 12, 13, 14, 18];
const res = max(intersection(tab, tab2))
console.log({
intersection: intersection(tab, tab2),
max: max(intersection(tab, tab2)),
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
You can translate that into straight javascript, especially if it's for a homework assignment :).
The approach is as follows ...
get the intersection of both arrays
get the maximum value of the just computed intersection
... which then boils down either to coming up with an own implementation of an intersection functionality or to making use of a third party library / helper functionality.
The below example code features one possible implementation of getIntersection which makes use of ...
Array.from in order to always ensure the processing of array parameters,
Array.prototype.sort in order to help optimally assign the participating arrays for the best computation performance,
Array.prototype.reduce and a Map instance for creating a lookup-table in order to achieve a more performant filter process when it comes to the actual computation of the intersection,
Array.prototype.filter and Map.prototype.has for finally computing the intersection result.
function getIntersection(firstIterable = [], secondIterable = []) {
const [
comparisonBase, // ... compare to the shorter array.
comparisonList, // ... filter from the longer array.
] = [Array.from(firstIterable), Array.from(secondIterable)]
// - ensure two arrays (line above)
// - and sort them according to each array's `length`.
.sort((a, b) => a.length - b.length);
// create a `Set` based lookup from the shorter array.
const itemLookup = new Set(comparisonBase);
// the intersection is the result of following filter task.
return comparisonList.filter(item => itemLookup.has(item));
}
const tab = [1, 2, 4, 5, 8, 9, 11, 15, 16, 17, 20, 21, 0];
const tab2 = [3, 4, 6, 7, 9, 10, 11, 12, 13, 14, 18, 19, 0];
console.log(
'intersection of `tab` and `tab2` ...',
getIntersection(tab, tab2)
);
console.log(
'max value of the intersection of `tab` and `tab2` ...',
Math.max(...getIntersection(tab, tab2))
);
This question already has answers here:
To find Index of Multidimensional Array in Javascript
(7 answers)
Get coordinates of an element in multidimentional array in Javascript [duplicate]
(2 answers)
How to find the index value of an two dimensional array in javascript
(2 answers)
Closed 2 years ago.
I have a grid like shown above, and I want to get the cell x and y coordinates with its number.
For example: cell number 18 => x = 3, y = 4
What I've already got:
const grid = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]
]
const width = grid[0].length //As my grid will always be regular, I just pick the first row's length
const height = grid.length
console.log(getXYCoords(8, grid))
function getXYCoords(cell, grid) {
//This is where I can't figure out how to do it
}
A nested for loop would solve this. First loop through all the rows, then through the columns of each row. y will indicate the current row and x the current column.
Check for a match within the second loop. If a match is found, then return an object with the x and y coordinates in an object.
const grid = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]
];
const rows = grid.length;
const columns = grid[0].length;
function getXYCoords(grid, cell) {
for (let y = 0; y < rows; y++) {
for (let x = 0; x < columns; x++) {
if (grid[y][x] === cell) {
return ({x, y});
}
}
}
return null;
}
console.log(getXYCoords(grid, 8))
console.log(getXYCoords(grid, 19))
console.log(getXYCoords(grid, 22))
Simple 2 loops solution would get you get the result.
const grid = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]
]
const width = grid[0].length //As my grid will always be regular, I just pick the first row's length
const height = grid.length
const res = getXYCoords(8, grid);
console.log(res, grid[res.x][res.y]) // verifies the results
function getXYCoords(cell, grid) {
let x, y;
for(x in grid) {
for(y in grid[x]){
if (grid[x][y] === cell) {
return { x, y };
}
}
}
}
You can also improve the performance of your function, currently at O(n^2) by memoizing the function.
I need to console.log every number that is greater than 10 from this row
[ 10, 10, 11, 12, 156, 9, 3, 5, 1, 61, 89, 5, 6]
I know it should be something like this
var row = [ 10, 10, 11, 12, 156, 9, 3, 5, 1, 61, 89, 5, 6];
for (var i = 0; i<row; i++)
{
console.log(niz[i]);
}
Well you could either use a for loop or mapping. For loop would be like this:
for (var i = 0; i<row.length; i++)
{
if (row[i] > 10)
console.log(row[i]);
}
To use mapping:
row.map(function(element){
if (element > 10)
console.log(element);
});
As you stated in the question, you need to use a for-loop to iterate trough all the items in your array. This is almost done correctly, but instead of doing i<row, you need to check against the length of the row (row.length).
In your case, i will be the index in your list, and it will increment with one (i++) in each iteration in the for-loop until you reach the number of items in rows.
The thing that you are missing is a if-statement to check if the item in the array is greater than 10.
I've tried to explain each line with a comment.
var row = [10, 10, 11, 12, 156, 9, 3, 5, 1, 61, 89, 5, 6];
var items = row.length; // number of items in your array
for (var i = 0; i < items; i++) { // iterate trough all the items
var numberInRow = row[i]; // the number with index number i in rows
var isGreaterThanTen = numberInRow > 10; // true if the number is greater than ten
if (isGreaterThanTen) { // will execute if isGreaterThanTen is true
console.log(numberInRow); // print number greater than 10 to console.
}
}
A forEach-loop seems a nice way of solving your problem:
var row = [ 10, 10, 11, 12, 156, 9, 3, 5, 1, 61, 89, 5, 6];
row.forEach(function(x){if(x>10){console.log(x)}})
or even shorter
[10, 10, 11, 12, 156, 9, 3, 5, 1, 61, 89, 5, 6].forEach(function(x){if(x>10){console.log(x)}})
The output in both cases:
11
12
156
61
89
I have 7 arrays in javascript and I need to find values that are present in all of them.
I don't think I'm the first one to ask this but I can't find a solution for this. I read many answers but they all compare only 2 arrays and that logic don't work for multiple arrays.
I tried functions proposed in Simplest code for array intersection in javascript but they don't fit the kind of arrays I have.
The arrays I have can have different lengths in elements and the element's lengtt can vary too. I also may have zero item arrays in which they should not be compared against.
The main problem is with different number lengths. All functions I tried require sorting but this causes a problem.
Given this arrays:
xnombre = [1,2,3,4,5,24,44,124,125,165];
xacomp = [1,5,44,55,124];
xeje = [];
xanio = [1,5,44,55,124];
xini = [1,5,44,55,124];
xaporte = [1,5,44,55,122,123,124,144,155,166,245];
xpcia = [2,1,3,4,6,5,7,9,12,12,14,15,44,16,17,19,124];
The first to arrays are sorted to:
[1, 124, 125, 165, 2, 24, 3, 4, 44, 5]
[1, 124, 44, 5, 55]
Which when I "intersect" I only get [1,124] but 44 and 5 are missed.
Any help would be appreciated.
Thanks
The function from the other question works, but you have to sort your array numerically, not lexicographically, since you are working with numbers, not strings.
function sortNumber(a,b) {
return a - b;
}
var xnombre = [1,2,3,4,5,24,44,124,125,165];
var xacomp = [1,5,44,55,124];
xnombre.sort(sortNumber);
xacomp.sort(sortNumber);
DEMO
To apply this to multiple arrays, you could apply this function consecutively:
// var result = intersect(a, b, c, ...);
function intersect(var_args) {
// sort arrays here or beforehand
var target = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i].length > 0) {
target = intersection_safe(target, arguments[i]);
}
}
return target;
}
This requires some of the new array methods, but it produces your desired output.
function intersection() {
var arrs = Array.prototype.filter.call(arguments, function (a) {
return a.length > 0;
}).sort(function (a, b) { // sort the arrays, so that we test the shortest.
return a.length - b.length;
});
var rest = arrs.slice(1),
test = arrs[0];
return test.filter(function (x) { return rest.every(function (a) { return a.indexOf(x) !== -1; }); });
}
var xnombre = [1, 2, 3, 4, 5, 24, 44, 124, 125, 165],
xacomp = [1, 5, 44, 55, 124],
xeje = [],
xanio = [1, 5, 44, 55, 124],
xini = [1, 5, 44, 55, 124],
xaporte = [1, 5, 44, 55, 122, 123, 124, 144, 155, 166, 245],
xpcia = [2, 1, 3, 4, 6, 5, 7, 9, 12, 12, 14, 15, 44, 16, 17, 19, 124];
intersection(xnombre, xacomp, xeje, xanio, xini, xaporte, xpcia)
// => [1, 5, 44, 124]
I tried your problem with underscore.
var _ = require('underscore');
xnombre = [1,2,3,4,5,24,44,124,125,165];
xacomp = [1,5,44,55,124];
xeje = [];
xanio = [1,5,44,55,124];
xini = [1,5,44,55,124];
xaporte = [1,5,44,55,122,123,124,144,155,166,245];
xpcia = [2,1,3,4,6,5,7,9,12,12,14,15,44,16,17,19,124];
var result = _.intersection(xnombre,xacomp,xanio,xini,xaporte,xpcia);
console.log(result);
But as you see that I haven't given the empty array, so somehow you have to ignore empty array.
Fiddle