Related
Note: Not a duplicate problem.. here I need to skip empty arrays.
Say I have several arrays like:
var a = [1, 2, 3, 4],
b = [2, 4],
c = [],
d = [4];
Using following function, I could get the desired result: [4]
var a = [1, 2, 3, 4],
b = [2, 4],
c = [],
d = [4];
var res = [a, b, c, d].reduce((previous, current) =>
!previous.length || previous.filter((x) => !current.length || current.includes(x)),
);
console.log(res)
I included !current.length || above to bypass empty array c. But this doesn't work if first array in the collection i.e. a is empty. The result would be [].
This code will work as you expected (vanilla JS, support old browsers):
var a = [1, 2, 3, 4],
b = [2, 4],
c = [],
d = [4];
var res = [a, b, c, d].reduce(function(acc, arr) {
// ignore empty array
if(arr.length == 0) return acc;
// assign first non-empty array to accumudation
if(acc.length == 0) return arr;
// otherwise, accumudation will be insection of current accomudation and current array
return acc.filter(function(n) {
return arr.indexOf(n) !== -1;
});
}, []);
console.log(res)
Just filter. Makes the code much more readable
var a = [1, 2, 3, 4],
b = [2, 4],
c = [],
d = [4];
var res = [c, b, a, d].filter(arr => arr.length).reduce((previous, current) =>
previous.filter((x) => current.includes(x)),
);
console.log(res)
This question already has answers here:
Dividing an array by filter function
(14 answers)
Closed 4 years ago.
Is there a way to filter an array of objects to retrieve an array of the values I need but also remove the filtered values from the original list. Something like this
let array = [1, 2, 3, 4, 5];
const filteredList, listContainingRemainingValues = array.filter(value => value > 3);
Output:
filteredList = [4, 5];
listContainingRemainingValues = [1, 2, 3];
Is there any built in functionality to do this already in Javascript or will i have to roll my own?
You could take an array as temporary storage for the wanted result.
const
array = [1, 2, 3, 4, 5],
[remaining, filtered] = array.reduce((r, v) => (r[+(v > 3)].push(v), r), [[], []]);
console.log(filtered);
console.log(remaining);
Same with lodash's _.partition
const
array = [1, 2, 3, 4, 5],
[filtered, remaining] = _.partition(array, v => v > 3);
console.log(filtered);
console.log(remaining);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Here's one option:
const array = [1, 2, 3, 4, 5];
// Get all the indices we want to keep:
const matchingIndices = array
.map((v, i) => [i, v > 3])
.filter((el) => el[1])
.map((el) => el[0]);
// Filter the input array by indices we want/don't want
const matching = array.filter((v, i) => matchingIndices.indexOf(i) >= 0);
const nonMatching = array.filter((v, i) => matchingIndices.indexOf(i) < 0);
Use 2 filters
let array = [1, 2, 3, 4, 5];
let filteredList = array.filter(value => value > 3);
let listContainingRemainingValues = array.filter(f => !filteredList.includes(f))
console.log(filteredList)
console.log(listContainingRemainingValues)
Here's one of the way using underscore library:
var data = [1, 2, 3, 4, 5]
var x = _.reject(data, function(num){ return num > 3; });
var y = _.difference(data, x);
console.log(x);
console.log(y);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
Sort the array, find the index of your threshold value and then splice it in order to remove the elements from the input array and to return the removed elements:
const array = [1, 2, 3, 4, 5];
// just if the input array is not already sorted
array.sort();
const removedElements = removeAndGet(array, 3);
console.log('input array:', array);
console.log('removed elements:', removedElements)
function removeAndGet(input, thresholdValue) {
const ind = input.findIndex(a => a > thresholdValue);
return ind > -1 ? input.splice(ind) : [];
}
This is my array of arrays:
arr_1 = [1,2,3]
arr_2 = [4,5,6]
arr_3 = [7,8,9]
arr = [arr_1, arr_2, arr_3]
arr = [[1,2,3], [4,5,6], [7,8,9]]
What I want to do is push all elements like so that the final array is like the following and insert another element at the beginning of my array:
arr = [[i,1,2], [3,4,5], [6,7,8], [9]]
All sub-arrays must not be more than 3 elements.
Thanks for your help.
You could visit all inner arrays and unshift the leftover values from the previous loop.
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
chunk = 3,
item = 'x',
i = 0,
temp = [item];
while (i < array.length) {
array[i].unshift(...temp);
temp = array[i].splice(chunk, array[i].length - chunk);
i++;
}
if (temp.length) {
array.push(temp);
}
console.log(array.map(a => a.join(' ')));
You can use the function reduce
var arr = [[1,2,3], [4,5,6], [7,8,9]],
newElem = "newOne",
all = [newElem, ...arr.reduce((a, c) => [...a, ...c], [])], // All together
// Build the desired output asking for the result of:
// element mod 3 === 0
result = all.reduce((a, c, i) => {
if (i % 3 === 0) a.push([c]);
else a[a.length - 1].push(c);
return a;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could move on each iteration last element from previous array to next one and if the last sub-array has more then 3 elements then remove the last one and add it to new array.
let arr_1 = [1, 2, 3],
arr_2 = [4, 5, 6],
arr_3 = [7, 8, 9],
arr = [arr_1, arr_2, arr_3]
setInterval(function() {
const last = arr.length - 1;
const newElement = parseInt(Math.random() * 30)
arr.forEach((a, i) => {
if(i == 0) a.unshift(newElement);
if(arr[i + 1]) arr[i + 1].unshift(a.pop())
else if(arr[last].length > 3) arr[last + 1] = [arr[last].pop()]
})
console.log(JSON.stringify(arr))
}, 1000)
You can do this quite succinctly with a simple unravel/ravel. It easy to adjust group size too.
let arr = [ [1,2,3], [4,5,6], [7,8,9]]
let newEl = 0
let groupSize = 3
var newArr = [];
var unravelled = arr.reduce((a, c) => a.concat(c), [newEl])
while(unravelled.length) newArr.push(unravelled.splice(0,groupSize));
console.log(newArr)
arr_1 = [1, 2, 3]
arr_2 = [4, 5, 6]
arr_3 = [7, 8, 9]
arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
function reassignChunk(x) {
// create an array which will be used to store unwrapped values
var newArray = [];
arr.forEach(function(elem) {
newArray.push(...elem); //using spread operator to unwrap values
});
newArray.unshift(x, limit)
var modArray = [];
var m, j, temparray, chunk = 3;
for (m = 0; m < newArray.length; m = m + limit) {
// creatinging new array using slice
modArray.push(newArray.slice(m, m + limit));
}
console.log(modArray)
}
reassignChunk(13, 3)
arr = [[i,1,2], [3,4,5], [6,7,8], [9]]
Assuming all your elements are numbers, you can do it like this:
Prepend i to the array
Flatten the array
Convert the array to a comma-separated string
Split the string into chunks of at most 3 numeric substrings (2 commas)
Convert the chunks back into arrays of numbers
const arr_1 = [1,2,3];
const arr_2 = [4,5,6];
const arr_3 = [7,8,9];
const i = 42;
const result = [i,...arr_1,...arr_2,...arr_3].join()
.match(/(?:[^,]+(,|$)){1,2}[^,]*/g).map( x => x.split(',').map(Number) )
;
console.log( result );
You may do your 2d unshifting simply as follows;
var arr_1 = [1,2,3],
arr_2 = [4,5,6],
arr_3 = [7,8,9],
arr = [arr_1, arr_2, arr_3],
us2d = (a2d,...is) => is.concat(...a2d)
.reduce((r,e,i) => (i%3 ? r[r.length-1].push(e)
: r.push([e]), r), []);
console.log(JSON.stringify(us2d(arr,0)));
console.log(JSON.stringify(us2d(arr,-2,-1,0)));
The output that I want to have is newArray = [4, 9, 16, 25]. But I don't get it. Where did I make errors? Please help me.
var array = [2, 3, 4, 5];
var result = [];
function multiply(a) {
return a * a;
}
function newArray (a) {
for (i=0; i<a.lenght; i++){
result.push(multiply(a.value));
}
}
var newArray = newArray(array);
var array = [2, 3, 4, 5];
function multiply(a) {
return a * a;
}
function newArray (a) {
return a.map(multiply)
}
var result = newArray(array);
console.log(result)
This is another way to do it
const array = [2,3,4,5];
function multipliedArray(arr) {
return arr.map(x => x * x);
}
console.log(multipliedArray(array));
Keeping your logic as it is.
You misspelled a.length.
And you missed the index with array a.
var array = [2, 3, 4, 5];
var result = [];
function multiply(a) {
return a * a;
}
function newArray (a) {
for (i=0; i<a.length; i++){ //spelling mistake
result.push(multiply(a[i])); // index should be used
}
return result;
}
console.log(newArray(array));
I found that if I use ES6, I can change the codes like the following.
const arrayPast = [2, 3, 4, 5];
const result = [];
const appendArray = arrayPast.map(x => x * x);
result.push(appendArray);
Another thought, using forEach
const oldArray = [3, 4, 5, 6];
const square = [];
const newArray = oldArray.forEach((x) => square.push(x * x));
In JavaScript, I have the following array
var arr = [5, 10, 2, 7];
From that array, I would like to get an array containing only the indexes of the items that are less than 10. So, in the above example, the indexes array would be
var indexes = [0, 2, 3];
Now, I want something simlar to filter, but that would return the indexes.
If I try filter, this is how it will work
var newArr = arr.filter(function (d) {
return (d < 10);
});
// newArr will be: [5, 2, 7];
This is not what I want. I want something along the following lines (note this is a pseudo-code)
var indexes = arr.filter(function (d) {
/* SOMETHING ALONG THE FOLLOWING PSEUDOCODE */
/* return Index of filter (d < 10); */
});
// indexes will be: [0, 2, 3];
How can I do that? Thanks.
Use a reducer.
var arr = [5, 10, 2, 7];
var newArr = arr.reduce(function(acc, curr, index) {
if (curr < 10) {
acc.push(index);
}
return acc;
}, []);
console.log(newArr);
You can use a forEach loop:
const arr = [5, 10, 2, 7];
const customFilter = (arr, min) => {
const result = [];
arr.forEach((element, index) => {
if (element < min) {
result.push(index);
}
});
return result;
}
console.log(customFilter(arr, 10));
You can use array#reduce and add indexes whose value is greater than 10.
var arr = [5, 10, 2, 7];
var indexes = arr.reduce((r, d, i) => d < 10 ? (r.push(i), r) : r , []);
console.log(indexes);