Related
I'm trying to write a function in Javascript that accepts a nested array and number as two arguments and returns a new nested array with the last couple items removed in each inside array as indicated by the number argument.
For example:
*/ removeColumns([[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]], 2);
=> [[1, 2],
[1, 2],
[1, 2],
[1, 2]]
*/
I am attaching the code have written so far. This gives me a return of [[3, 4], [3, 4]. I thought the splice function always removes array elements after the provided index but here it seems to be removing elements before the index. What am I doing wrong here?
const removeColumns = (originalGrid, numColumns) => {
for (let i = 0; i < originalGrid.length; i++) {
console.log(originalGrid[i].splice(originalGrid.length - numColumns, numColumns))
console.log(originalGrid[i])
}
return originalGrid
}
let originalGrid = [
[1, 2, 3, 4],
[1, 2, 3, 4]
];
console.log(removeColumns(originalGrid, 2))
I think that should fix your issue:
originalGrid[i].length - numColumns, numColumns)
In your example
let originalGrid = [
[1, 2, 3, 4],
[1, 2, 3, 4]
];
console.log(originalGrid.length) //2
console.log(originalGrid[0].length) //4
console.log(originalGrid[1].length) //4
So in the loop don't forget to add the index:
console.log(originalGrid[i].splice(originalGrid[i].length - numColumns, numColumns))
Write a filter function. Then, you can choose which column "section" to include.
const originalGrid = [
[1, 2, 3, 4],
[1, 2, 3, 4]
];
const filter = (data, from, to) => data.map(a => a.splice(from, to));
console.log(filter(originalGrid, 0, 2));
If I have one array:
let x= [0,1,2,3,5]
And I have an array with several subarrays:
let winningIndices = [[0, 1, 2], [6, 7, 8], [0, 3, 6], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
How can I check if array x contains all of the elements of any one subarray.
In other words, how can I check if array x has combinations of either the numbers 0,1,2 or 6,7,8...
Thanks in advance
"How can I check if array x contains all of the elements of any one subarray."
Here's the most straightforward functional interpretation.
const won = winningIndices.some(indices=>
indices.every(
item=>x.includes(item)
)
)
This could be an option. If you'd like to remove xIncludesItem key from result, just map it again.
const winningIndices = [
[0, 1, 2],
[6, 7, 8],
[0, 3, 6],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
const x = [0, 1, 2, 3, 5];
const result = winningIndices
.map((item) => {
const xIncludesItem = item
.map((i) => x.includes(i))
.every(includes => includes);
return { item, xIncludesItem };
})
.filter(result => result.xIncludesItem);
console.log(result);
Array.includes is much slower than Set.has. A slightly more performant solution based on Ted Brownlow's solution would be:
const setX = new Set(x);
const won = winningIndices.some(indices=>
indices.every(
item=>setX.has(item)
)
)
Could I have some guidance on how to extract multiple columns from a two-dimensional array like the below using JavaScript?
Array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
the simple methods I've seen so far using forEach or map will allow extraction of ONE column at a time, is there a way to nest it somehow to extract whichever column index one desire?
Let's say the desire output column is 1,2 and 4.
Output = [
[1, 2, 4],
[5, 6, 8],
[9,10,12],
];
EDIT:
Another problem I need to resolve is how to remove a row if it's Array[i][1]=0 or empty.
Let say we have extra array elements...
Array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[17, ,19,20],
[21,22,23,24],
];
The desired output is now...
Output = [
[1, 2, 4],
[5, 6, 8],
[9,10,12],
[21,22,24],
];
You can .map() each row in arr to a new array which you can obtain by using an inner .map() on an array of columns/indexes which you wish to obtain. The inner map will map each index to its associated value from the row, giving you the values at each column for each row.
See example below:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
const cols = [1, 2, 4];
const res = arr.map(r => cols.map(i => r[i-1]));
console.log(res);
Further details:
As you mentioned the first map exposes each inner array inside of arr to the inner mapping function:
cols.map(i => r[i-1])
This mapping function will loop through the indexes defined inside of cols and transform them into a new value. For example, say you're r is the second array:
[5, 6, 7, 8]
Performing cols.map(...) will loop over each element (denoted by i in the callback function) in [1, 2, 4]. For each element, we "transform" it into a new element:
i = 1
r = [5, 6, 7, 8]
new value: r[1-1] = 5
Next iteration we look at the next value in cols:
i = 2
r = [5, 6, 7, 8]
new value: r[2-1] = 6
Lastly, we look at the final value in cols:
i = 4
r = [5, 6, 7, 8]
new value: r[4-1] = 8
So the mapping function produces a new array which transforms the values from cols [1, 2, 4], into the values at those indexes in the current row to be [5, 6, 8]. This occurs for each inner array / row, producing the final result.
EDIT
As per your edit, you can apply the same logic from above to get your arrays with only the columns you desire. Once you have done that you can use .filter() to keep only the rows which have a truthy value in the second column. Keeping all the arrays with truthy values in the second column will remove the arrays with non-truthy values in the second column (falsy values) from your resulting array. 0 and undefined are both flasy values, so they are not kept.
See example below:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[17, ,19,20],
[21,22,23,24],
]
const cols = [1, 2, 4];
const col = 2;
const res = arr.filter(r => r[col-1]).map(r => cols.map(i => r[i-1]));
console.log(res);
If you have multiple columns you want to ignore, you can use .every() to ensure each (ie: every) column contains a truthy value. If they all do, then .every() will return true, keeping the column, otherwise, it will return false, removing the column:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[ ,17,19,20],
[21,22,23,24],
]
const cols = [1, 2, 4];
const col = [1, 2];
const res = arr.filter(r => col.every(c => r[c-1])).map(r => cols.map(i => r[i-1]));
console.log(res);
You can approach it the below given way. The solution is using the index parameter available in filter method .
Array.filter(currElem,index,array)
Since array is 0-indexed ,so I created the array with index you want in the data as [0,1,3] . You need to pass the data array and index array to the function .
var array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
var arrIndex = [0,1,3];
function extractData(arr,indexArr) {
return arr.map(obj => {
return obj.filter((ob,index) => {
if(indexArr.includes(index)){return ob}
})
})
}
console.log(extractData(array,arrIndex));
I'm trying to solve this problem. Essentially, I have a array of keys, and an array of values within objects, and I want those values to have keys.
Below is my best attempt so far - usually use python so this is a bit confusing for me.
var numbers = [3, 4, 5,6]
var selection = [[1, 2, 3, 4], [6, 5, 4, 3], [2, 9, 4]]
var result = [];
for (arr in selection) {
numbers.forEach(function (k, i) {
result[k] = arr[i]
})
};
console.log(result);
The output I'm looking for is like this,
results = [{3:1,4:2,5:3,6:4}, {..},..]
Love some pointers to getting the right output.
Note. This is for google appscript! So can't use certain javascript functions (MAP I think doesn't work, unsure of reduce).
Cheers!
Use map on selection and Object.assign
var numbers = [3, 4, 5, 6];
var selection = [
[1, 2, 3, 4],
[6, 5, 4, 3],
[2, 9, 4]
];
var result = selection.map(arr =>
Object.assign({}, ...arr.map((x, i) => ({ [numbers[i]]: x })))
);
console.log(result);
Create a separate function which take keys and values as arguments and convert it into object using reduce(). Then apply map() on selections and make an object for each subarray using that function
var numbers = [3, 4, 5,6]
var selection = [[1, 2, 3, 4], [6, 5, 4, 3], [2, 9, 4]]
function makeObject(keys, values){
return keys.reduce((obj, key, i) => ({...obj, [key]: values[i]}),{});
}
const res = selection.map(x => makeObject(numbers, x));
console.log(res)
Create a new object from scratch for each number array:
const selection = [
[1, 2, 3, 4],
[6, 5, 4, 3],
[2, 9, 4],
];
function objMaker(numarr) {
const numbers = [3, 4, 5, 6];
numarr.forEach((num, i) => (this[numbers[i]] = num));
}
console.info(selection.map(numarr => new objMaker(numarr)));
I have a multidimensional array like below and I want to shift column positions using javascript or ES6 with no jquery or any other plugins.
Eg: Initial array will look like this.
1|2|3|4
2|2|6|4
4|2|3|4
9|2|7|4
How can I shift the 4th column to 1st position so that it will look like this?
4|1|2|3
4|2|2|6
4|4|2|3
4|9|2|7
Could someone can help with logic to shift any columns like this?
You could assing a mapped outer array with new items by slicing the inner arrays with a given index.
For getting the original sort, you could shiftby the delta of length and index.
const shift = (array, index) => array.map(a => [...a.slice(index), ...a.slice(0, index)]);
var array = [[1, 2, 3, 4], [2, 2, 6, 4], [4, 2, 3, 4], [9, 2, 7, 4]],
index = 3;
array = shift(array, index);
console.log(array.map(a => a.join(' ')));
array = shift(array, array[0].length - index);
console.log(array.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use array.map to re-arrange the values:
function rearrange(rows, pos) {
return rows.map(function(cols) {
return pos.map(function(i) {
return cols[i];
});
});
}
var old_arr;
var new_arr;
old_arr = [
[1, 2, 3, 4],
[2, 2, 6, 4],
[4, 2, 3, 4],
[9, 2, 7, 4]
];
new_arr = rearrange(old_arr, [3, 0, 1, 2]);
console.log(new_arr);
old_arr = [
[1, 2, 3, 4],
[2, 2, 6, 4],
[4, 2, 3, 4],
[9, 2, 7, 4]
];
new_arr = rearrange(old_arr, [3, 2, 1, 0]);
console.log(new_arr);