Extract subarray from a multidimensional array and mutate the original array - javascript

I want to extract a subarray from a multidimensional array and have the original array be mutated so it no longer contains the extracted subarray
If I have a multidimensional array called originalArray
I can extract a subarray from a list of header indices
function newArrCols(arrayofarray, indexlist) {
return arrayofarray.map(function (array) {
return indexlist.map(function (idx) {
return array[idx];
});
});
}
So If:
idxList = [1,2,5,7]
subArray = newArrCols(originalArray, idxList)
Know I have to delete the subArray from the originalArray
//Remove columns from original arr w.r.t headeridx
for (var i = 0; i <= idxList.length - 1; i++) {
originalArray.map(a => a.splice(idxList[i], 1));
}
Is there a way to do this in a single process I would like to skip the deleting part
Thanks

EDIT:
Create a temporary empty array that will hold the items of the originalArray that aren't included in the idxList
let tempArray = [];
Create the subArray and populate the tempArray using Array.reduce():
let subArray = originalArray.reduce((accumulator, current, index) => {
if (idxList.includes(index)) {
//if the current index is included in the idxList array,
//push the current value to the accumulator
accumulator.push(current);
} else {
//push the current value to the `tempArray`.
tempArray.push(current)
}
return accumulator;
}, []);
Replace the originalArray with a deep clone of the tempArray
originalArray = JSON.parse(JSON.stringify(tempArray));
Working snippet below.
let originalArray = [
[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
[5, 5, 5, 5],
[6, 6, 6, 6],
[7, 7, 7, 7],
];
let idxList = [1, 2, 5, 7];
let tempArray = [];
//Can also be written in a one line arrow function
let subArray = originalArray.reduce((a, c, i) => (idxList.includes(i) ? a.push(c) : tempArray.push(c), a), []);
originalArray = JSON.parse(JSON.stringify(tempArray));
tempArray = [];
console.log({
subArray: JSON.stringify(subArray)
});
console.log({
originalArrayAfter: JSON.stringify(originalArray)
});

Related

Javascript - Numeric input to obtain variable length array data

I have a dozen arrays (hypothetically) and each has a completely different length. Is there a way that I can name them such that a numeric input into a function will return an array corresponding to that specific number?
This makes no sense so here's kinda what I want:
var dQw4w9WgXcQ;
const array1 = [1,1,1,1,1,1,1,1,1,1];
const array2 = [1,2,3,4];
const array3 = [1,3,6];
function getArray(id){
output = constNamed('array' + id);
}
//getArray(2) sets dQw4w9WgXcQ to [1,2,3,4]
and yes, dQw4w9WgXcQ is just something I totally typed on accident
USING OBJECT
1) You can creat an object that contain all arrays as:
const arrays = {
array1,
array2,
array3,
};
2) Assign the result getArray(2) to dQw4w9WgXcQ by just returning the array from object.
return arrays[`array${id}`];
var dQw4w9WgXcQ;
const array1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
const array2 = [1, 2, 3, 4];
const array3 = [1, 3, 6];
function getArray(id) {
const arrays = {
array1,
array2,
array3,
};
return arrays[`array${id}`];
}
dQw4w9WgXcQ = getArray(2);
console.log(dQw4w9WgXcQ);
NOTE: If you want to set value to dQw4w9WgXcQ directly after the invocation of the function getArray(2)
var dQw4w9WgXcQ;
const array1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
const array2 = [1, 2, 3, 4];
const array3 = [1, 3, 6];
function getArray(id) {
const arrays = {
array1,
array2,
array3,
};
dQw4w9WgXcQ = arrays[`array${id}`];
}
getArray(2);
console.log(dQw4w9WgXcQ);
USING ARRAY
var dQw4w9WgXcQ;
const array1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
const array2 = [1, 2, 3, 4];
const array3 = [1, 3, 6];
function getArray(id) {
const arrays = [array1, array2, array3];
return arrays[id - 1];
}
dQw4w9WgXcQ = getArray(2);
console.log(dQw4w9WgXcQ);
Have one array contain all the arrays. You can then pass that array into the function as an argument along with the id, and use find to return the array at the index of id - 1 (because indexes are zero-based). If find can't meet the condition it will return undefined.
const arr = [
[1,1,1,1,1,1,1,1,1,1],
[1,2,3,4],
[1,3,6]
];
function getArray(arr, id){
return arr.find((a, index) => index === id - 1);
}
console.log(getArray(arr, 2));
console.log(getArray(arr, 4));
Note all we're doing here is assigning

combining "columns" in multiple arrays

I have an array of arrays:
var arr = [
[0, 3, 3],
[0, 4, 3],
[1, 3, 4],
[1, 4, 4]
];
I want to create a new array that combines the contents of each index of the inner arrays. For example, the first elements at index 0 of each of the inner arrays are 0, 0, 1, and 1. I want to create a new array that combines those elements so that I end up with [0, 1] (I don't want duplicates in the new array). The next "column" is 3, 4, 3, and 4. So I'd want an array of [3, 4].
The end result I want is
[
[0, 1],
[3, 4],
[3, 4]
]
I can't quite figure out how to do this.
May not be the most efficient, but does meet you cryptic requirements.
var arr = [
[0, 3, 3],
[0, 4, 3],
[1, 3, 4],
[1, 4, 4]
];
const unique = (myArray) => [...new Set(myArray)];
let x, y,
tarr = [], // temp array
farr = []; // final array
for (x=0; x<arr.length; x++) {
tarr.length = 0;
for (y=0; y<arr[x].length; y++) {
tarr.push(arr[y][x])
}
farr.push( unique(tarr) );
}
console.log(farr.join('\n'));
Here another solution.
const result = (arr) => {
let index = 0;
const min = Math.min(...arr.map(r => r.length)) // get min length
const grid = [];
while (index < min) { // loop with min
let s = new Set(); // using set to keep unique values
arr.forEach(r => s.add(r[index])); // pick value
grid.push([...s]); // get array from set
index++;
}
return grid
}
const array = [ [0, 3, 3], [0, 4, 3], [1, 3, 4], [1, 4, 4] ];
console.log(result(array))

Javascript: How to find difference for two number arrays

I need to create a new array made up of unique elements from two separate arrays.
I have converted both arrays into a single array and then converted this into an object to check the frequency of the elements. If the value of an object property is 1 (making it a unique property), I want to return it to an array (minus the value). Is there a straightforward way to achieve this?
Edits: Moved result outside for loop. Expected output should be [4]
function diffArray(arr1, arr2) {
var finalArr = [];
var countObj = {};
var newArr = [...arr1, ...arr2];
for (var i = 0; i < newArr.length; i++) {
if (!countObj[newArr[i]]) countObj[newArr[i]] = 0;
++countObj[newArr[i]];
}
for (var key in countObj) {
if (countObj[key] === 1) {
finalArr.push(key);
}
} return finalArr;
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
If I understand correctly, you're wanting to find the difference between arr1 and arr2, and returns that difference (if any) as a new array of items (that are distinct in either array).
There are a number of ways this can be achieved. One approach is as follows:
function diffArray(arr1, arr2) {
const result = [];
const combination = [...arr1, ...arr2];
/* Obtain set of unique values from each array */
const set1 = new Set(arr1);
const set2 = new Set(arr2);
for(const item of combination) {
/* Iterate combined array, adding values to result that aren't
present in both arrays (ie exist in one or the other, "difference") */
if(!(set1.has(item) && set2.has(item))) {
result.push(item);
}
}
return result;
}
console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]), " should be [4]");
console.log(diffArray([1, 2, 3, 5, 8], [1, 2, 3, 5]), " should be [8]");
console.log(diffArray([1, 2, 3, 5, 8], [1, 2, 3, 5, 9]), " should be [8, 9]");
console.log(diffArray([1, 2], [1, 2]), " should be []");

Sort the values in the array in the recurring order provided by another array?

How to sort randomly placed values in one array so that it matches the order provided by another array, but instead of appending the duplicates one after the other, the function should append the group of values, provided by the order variable, one after the other.
Input:
const array = [1, 5, 4, 3, 5, 3, 1, 5, 4];
const order = [5, 1, 3, 4];
Correct Output:
const correctlyOrderedArray = [5, 1, 3, 4, 5, 1, 3, 4, 5];
Wrong Output:
const wronglyOrderedArray = [5, 5, 5, 1, 1, 3, 3, 4, 4];
Two functions. The first one does the actual sorting and uses the second one inside itself.
Primary function:
function sortByOrder (array, order) {
const arrayOfArrays = order.map(v => {
return [...Array(howMany(v, array))].map(undef => v);
});
const tempArray = [];
arrayOfArrays.forEach((subArr, i) => {
let index = order.indexOf(order[i]);
subArr.forEach(duplicate => {
tempArray[index] = duplicate;
index += order.length;
});
});
return tempArray.filter(v => v);
}
Subordinate function:
function howMany(value, array) {
const regExp = new RegExp(value, 'g');
return (array.join(' ').match(regExp) || []).length;
}
If we suppose that the array order contains all the non duplicated elements of the array array, one way to achieve the sorting could be to copy the element of order using a modulo so that, we can restart the copy from the beginning.
const array = [1, 5, 4, 3, 5, 3, 1, 5, 4];
const order = [5, 1, 3, 4];
var newValue = []
for(var i = 0; i < array.length; i++){
newValue.push(order[i % order.length])
}
console.log(newValue)
We could iterate over the order and shift out elements out of our array until its empty:
const array = [1, 5, 4, 3, 5, 3, 1, 5, 4];
const order = [5, 1, 3, 4];
let i = 0, exit = false;
const result = [];
while(array.length){
const found = array.findIndex(el => el === order[i % order.length]);
if(found+1){
result.push( array.splice(found, 1)[0] );
exit = false;
}
if(i && i % order.length){
if(exit){
result.push(...array); //concat the rest
break;
}
exit = true;
}
i++;
}
The exit boolean will terminate the program if one order iteration did not found anything, e.g.:
const order = [1,2,3], array = [4,5,6,1,2,3,1,2,3];
Let it run!

Remove multiple elements from array by value in JS

When I want to remove one element, it is easy. This is my function:
function removeValues(array, value) {
for(var i=0; i<array.length; i++) {
if(array[i] == value) {
array.splice(i, 1);
break;
}
}
return array;
}
But how do I remove multiple elements?
Here a simple version using ES7:
// removing values
let items = [1, 2, 3, 4];
let valuesToRemove = [1, 3, 4]
items = items.filter((i) => !valuesToRemove.includes(i))
For a simple version for ES6
// removing values
let items =[1, 2, 3, 4];
let valuesToRemove = [1, 3, 4]
items = items.filter((i) => (valuesToRemove.indexOf(i) === -1))
const items = [0, 1, 2, 3, 4];
[1, 4, 3].reverse().forEach((index) => {
items.splice(index, 1)
})
// [0, 2, 4]
I believe you will find the kind of functionality you are looking for in Javascript's built in array functions... particularily Array.map(); and Array.filter();
//Array Filter
function isBigEnough(value) {
return value >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
//Array Map (Can also be used to filter)
var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
return num * 2;
});
// doubles is now [2, 8, 18]. numbers is still [1, 4, 9]
/////UPDATE REFLECTING REMOVAL OF VALUES USING ARRAY MAP
var a = [1,2,3,4,5,6];
a.map(function(v,i){
if(v%2==0){
a.pop(i);
}
});
console.log(a);
// as shown above all array functions can be used within the call back to filter the original array. Alternativelty another array could be populated within the function and then aassigned to the variable a effectivley reducing the array.

Categories