Related
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
I have an array arr:
arr = [0,1,2,3,4,5]
How can I reorder/ shift multiple elements? For example,
I want to remove 0,2 and 3 and put them at index 4 so that the final array should be [1,0,2,3,4,5]
In the above example, index 4 is with the perspective of the original array, not the final array.
I tried using splice like this:
items = [0,2,3] // items to be reordered
indexes = [0,2,3] // get their indexes
arr = [...arr.filter((it)=> !indexes.includes(arr.indexOf(it)))]
arr.splice(4, 0, ...items)
// result [1, 4, 5, 0, 2, 3]
The above is not the intended result
This solution mutates the array.
You could store the value at the inser position and remove the items and splice the removed items after the index of the stored item.
position v
index 0 1 2 3 4
array [0, 1, 2, 3, 4, 5] store value at index
1 4 5 rest array after removing items
1 4 [0 2 3] 5 splice with removed items
var array = [0, 1, 2, 3, 4, 5],
remove = [0, 2, 3],
insertAtIndex = 4,
valueAtPosition = array[insertAtIndex];
remove.forEach(v => array.splice(array.indexOf(v), 1));
array.splice(array.indexOf(valueAtPosition) + 1, 0, ...remove);
console.log(...array);
You can first remove the given elements and then use splice() to add them at the required index.
function shiftElementsTo(arr, inds, final){
let set = new Set(inds);
let removed = inds.map(x => arr[x]);
arr = arr.filter((x, i) => !set.has(i));
arr.splice(final, 0, ...removed);
return arr;
}
console.log(shiftElementsTo([0, 1, 2, 3, 4, 5], [0, 2, 3], 2))
Try to use this approach:
let arr = [0,1,2,3,4,5];
let rmv = [0, 2, 3];
const remove = (src, rem, i ) => {
const arrWithIndexes = src.map((a, i) => { return {value: a, index: i}});
const filtered = arrWithIndexes.filter(f => !rem.some(s=> s === f.value));
const indexToInsert = filtered.findIndex(f=>f.index === i);
const result = filtered.map(f=> f.value);
result.splice(indexToInsert, 0, ...rem);
console.log(result);
}
console.log(remove(arr, rmv, 4));
Or if you know the desired index:
let arr = [0,1,2,3,4,5];
let rmv = [0, 2, 3];
const remove = (src, rem ) => {
const filtered = src.filter(f=> !rem.some(s=> s === f));
filtered.splice(2, 0, ...rmv)
console.log(filtered);
}
console.log(remove(arr, rmv));
const temp = [0, 2, 3];
const arr = [0, 1, 2, 3, 4, 5];
const index = arr[4];
// Accepts an array (temp) and returns a function to be used
// as the callback for `filter` which accepts an element
// and returns whether that element is in the temp array
const filterUsing = (arr) => (el) => !arr.includes(el);
// `filter` the elements from the main array
const filtered = arr.filter(filterUsing(temp));
// Find the new position of the element in `index`
const newIndex = filtered.findIndex(el => el === index);
// Splice in the temp array back into the filtered array
filtered.splice(newIndex, 0, ...temp);
console.log(filtered);
I have an array [1,1,1,1,2,3,4,5,5,6,7,8,8,8]
How can I get an array of the distinct duplicates [1,5,8] - each duplicate in the result only once, regardless of how many times it appears in the original array
my code:
var types = availControls.map(item => item.type);
var sorted_types = types.slice().sort();
availControlTypes = [];
for (var i = 0; i < sorted_types.length - 1, i++) {
if (sorted_types[i + 1] == sorted_types[i])
availControlTypes.push(sorted_types[i]);
}
This gets me the duplicates, but not unique.
This will do it
var input = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
let filterDuplicates = arr => [...new Set(arr.filter((item, index) => arr.indexOf(item) != index))]
console.log(filterDuplicates(input))
You need a for loop, with an object that will hold the number of times the number appeared in the array. When the count is already 1, we can add the item to the result. We should continue to increment the counter, so we won't add more than a single duplicate of the same number (although we can stop at 2).
function fn(arr) {
var counts = {};
var result = [];
var n;
for(var i = 0; i < arr.length; i++) {
n = arr[i]; // get the current number
if(counts[n] === 1) result.push(n); // if counts is exactly 1, we should add the number to results
counts[n] = (counts[n] || 0) +1; // increment the counter
}
return result;
}
var arr = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
var result = fn(arr);
console.log(result)
const dupes = arr =>
Array.from(
arr.reduce((acc, item) => {
acc.set(item, (acc.get(item) || 0) + 1);
return acc;
}, new Map())
)
.filter(x => x[1] > 1)
.map(x => x[0]);
const arr = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
console.log(dupes(arr));
// [ 1, 5, 8 ]
ES6 1 liner.
This is very similar to how we find unique values, except instead of filtering for 1st occurrences, we're filtering for 2nd occurrences.
let nthOccurrences = (a, n = 1) => a.filter((v, i) => a.filter((vv, ii) => vv === v && ii <= i).length === n);
let x = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
let uniques = nthOccurrences(x, 1);
let uniqueDuplicates = nthOccurrences(x, 2);
let uniqueTriplets = nthOccurrences(x, 3); // unique values with 3 or more occurrences
console.log(JSON.stringify(uniques));
console.log(JSON.stringify(uniqueDuplicates));
console.log(JSON.stringify(uniqueTriplets));
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!
If i have an array A = [1, 4, 3, 2] and B = [0, 2, 1, 2] I want to return a new array (A - B) with values [1, 2, 2, 0]. What is the most efficient approach to do this in javascript?
const A = [1, 4, 3, 2]
const B = [0, 2, 1, 2]
console.log(A.filter(n => !B.includes(n)))
Use map method
The map method takes three parameters in it's callback function like below
currentValue, index, array
var a = [1, 4, 3, 2],
b = [0, 2, 1, 2]
var x = a.map(function(item, index) {
// In this case item correspond to currentValue of array a,
// using index to get value from array b
return item - b[index];
})
console.log(x);
For Simple and efficient ever.
Check here : JsPref - For Vs Map Vs forEach
var a = [1, 4, 3, 2],
b = [0, 2, 1, 2],
x = [];
for(var i = 0;i<=b.length-1;i++)
x.push(a[i] - b[i]);
console.log(x);
const A = [1, 4, 3, 2]
const B = [0, 2, 1, 2]
const C = A.map((valueA, indexInA) => valueA - B[indexInA])
console.log(C) // [1, 2, 2, 0]
Here the map is returning the substraction operation for each number of the first array.
Note: this will not work if the arrays have different lengths
If you want to override values in the first table you can simply use forEach method for arrays forEach. ForEach method takes the same parameter as map method (element, index, array). It's similar with the previous answer with map keyword but here we are not returning the value but assign value by own.
var a = [1, 4, 3, 2],
b = [0, 2, 1, 2]
a.forEach(function(item, index, arr) {
// item - current value in the loop
// index - index for this value in the array
// arr - reference to analyzed array
arr[index] = item - b[index];
})
//in this case we override values in first array
console.log(a);
One-liner using ES6 for the array's of equal size in length:
let subResult = a.map((v, i) => v - b[i]); // [1, 2, 2, 0]
v = value, i = index
function subtract(operand1 = [], operand2 = []) {
console.log('array1', operand1, 'array2', operand2);
const obj1 = {};
if (operand1.length === operand2.length) {
return operand1.map(($op, i) => {
return $op - operand2[i];
})
}
throw new Error('collections are of different lengths');
}
// Test by generating a random array
function getRandomArray(total){
const pool = []
for (let i = 0; i < total; i++) {
pool.push(Math.floor(Math.random() * total));
}
return pool;
}
console.log(subtract(getRandomArray(10), getRandomArray(10)))
Time Complexity is O(n)
You can also compare your answer with a big collection of arrays.