I have this nested array
let thirarray = [
[2, 3, 4],
[5, 6, 7, 8],
[9, 10],
];
and what I'm trying to do is add the first element of each array so basically add 2+5+9= 16
I know I can access each element like this
//this is how i can access the first element of each array
console.log(thirarray[0][0]);
console.log(thirarray[1][0]);
console.log(thirarray[2][0]);
I know I can access with a nested loop all the elements like this
let suminsidearrays = 0;
for (i = 0; i < thirarray.length; i++) {
for (let j = 0; j < thirarray[i].length; j++) {
console.log(thirarray[i][j]);
suminsidearrays += thirarray[i][j];
console.log(suminsidearrays);
}
}
So my question is how can add the first element of each array?
simplest way to do it
let thirarray = [[2, 3, 4],[5, 6, 7, 8],[9, 10]];
var res=0
thirarray.forEach(a=>res+=a[0])
console.log(res)
This will sum the first element in each array inside the main array.
const array = [[2, 3, 4],[5, 6, 7, 8],[9, 10]]
let sum = array.reduce((a,c)=>a+c[0],0)
console.log(sum)
Update for new pattern requirement in the comment.
const array = [[2, 3, 4],[5, 6, 7, 8],[9, 10, 11]]
let i = 0, sum = array.reduce((a,c)=>a+c[i++],0)
console.log(sum)
I just want to add that I was able to solve it using what I learned from #holydragon.
So this is what I did
let fourthrarray = [
[20, 30, 40],
[50, 60, 70, 80],
[90, 100, 110, 120, 130],
];
let nextindexposition = 0;
let nextto = 0;
let sumeelsegundo = 0;
for (let i = 0; i < fourthrarray.length; i++) {
//this will allow me to see the 1st index position from each array
//i should expect to see 20,50,90
sumeelsegundo = fourthrarray[i][0];
//this will add the first index position of each array expected output will be 160
sumeelsegundo += fourthrarray[i][0];
console.log(sumeelsegundo);
//in order to add the next index position from each array i used two variable
//one that will store the result and the other one that will increase the index
//position by one on every iteration. this one will allow me to see the elements
//that will be added. expected elements will be 20,60,110
nextto = fourthrarray[i][nextindexposition++];
//this will be adding the elements expected output expected output 190
nextto += fourthrarray[i][nextindexposition++];
console.log(nextto);
}
Just to clarify something this solution works for adding numbers, If I wanted to multiply I just had to change the starting value on the variable nextto from 0 to 1.
Related
Today i'm facing a really weird problem.
I'm actually trying to delete numbers below a certain number in an array.
I have this array [1, 7, 2, 3, 90, 4, 70, 20] and I only want the numbers greater than 20 !
So I should have that in output : [90, 70]
But Instead I have this array : [7, 3, 90, 70, 20] ???
Here is my code :
function superior() {
var arr = [1, 7, 2, 3, 90, 4, 70, 20]
for (var i = 0; i < arr.length; i++) {
if (arr[i] < 20) {
arr.splice(arr.indexOf(arr[i]), 1);
} else {
break;
}
}
return arr;
}
console.log(superior());
Mutating an array while you're looping through it is always going to be tricky. If you shrink the size of the array, but don't change i, then you're can end up interacting with the wrong element of the array the next time through the loop. Also, using break will stop the loop from running entirely, and so skip the rest of the array. You may have meant to use continue, but since you're on the last line of the loop anyway, continue isn't needed.
Rather than trying to change the array and loop through it at the same time, i'd recommend creating a new array. Then you can loop through the old one unhindered:
const arr = [1, 7, 2, 3, 90, 4, 70, 20]
const newArr = []
for (const i = 0; i < arr.length; i++) {
if (arr[i] >= 20) {
newArr.push(arr[i]);
}
}
console.log(newArr)
Filtering an array like this is a very common thing to do, so there are built in tools to do it for you. Every array has a .filter method. You pass into it a function describing what elements you want to keep, and it will produce the new array for you:
const arr = [1, 7, 2, 3, 90, 4, 70, 20]
const newArr = arr.filter(element => element >= 20);
console.log(newArr)
You can filter them out according to a condition.
And replace your existing array with the filtered one. Or if you don't want to replace it, use another variable and assign the filtered value to that variable.
var newArray = array.filter(item => item > 20)
Check .filter()
var array = [1, 7, 2, 3, 90, 4, 70, 20];
array = array.filter(item => item > 20)
console.log(array)
You can use Array.filter()
var arr = [1, 7, 2, 3, 90, 4, 70, 20]
var filteredArr = arr.filter(item => item > 20);
console.log(filteredArr);
You could iterate from the end and omit indexOf, because you have already the index i.
This appoach loops from the end and after splicing, the remaining lower indices remains.
function superior() {
var array = [1, 7, 2, 3, 90, 4, 70, 20],
i = array.length;
while (i--) if (array[i] < 20) array.splice(i, 1);
return array;
}
console.log(superior());
Use temporary array to push new values.
function superior() {
var arr = [1, 7, 2, 3, 90, 4, 70, 20];
temp_arr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] > 20) {
temp_arr.push(arr[i]);
}
}
return temp_arr;
}
console.log(superior());
If I have an array with a set of numbers, and want to remove certain ones with the .filter method, I understand how to do this in when i need to remove a single item (or if i can use a mathematical expression), but can't get it to work with multiple items either purely by their value or position in the array.
In the following code I would like the new array selection to return the numbers 10, 12, 15
Also, I do need to do this with the filter() method only.
JS
let random = [4, 10, 12, 15, 30];
let selection = random.filter(function(num){
return num === [10, 12, 30];
});
You can use includes:
let random = [4, 10, 12, 15, 30, 10, 10, 12, 5];
let selection = random.filter(function(num){
var good = [10, 12, 30]
return good.includes(num);
});
console.log(selection)
Of if you prefer the terseness of arrow function:
let random = [4, 10, 12, 15, 30, 10, 10, 12, 5];
let selection = random.filter(num => [10, 12, 30].includes(num))
console.log(selection)
Forgive me if I do not understand it correctly, but if what you're looking for is to filter an array by the item's index, you can use the second parameter passed to the filter method's callback, which is the index.
let random = [4, 10, 12, 15, 30];
let selection = random.filter(function(num, index){
return index > 0 && index < 4;
});
console.log(selection);
You do need a condition that will return true or false when using filter, so the simplest way to do this with the filter method would be:
let random = [4, 10, 12, 15, 30];
let selection = random.filter(function(num){
if (num > 4 && num < 16) {return true};
});
The other way to do it would be filtering by position in the array and that would be better achieved with other array methods.
If I understand your question you want a function that takes a an array, checks if the elements are in your larger array and if they are there, removes them.
Filter might not be your best choice here because it doesn't alter the original array, it only makes a new array. Try using splice.
let random = [4, 10, 12, 15, 30];
function remove(array) {
for (var i = 0; i < array.length; i++) {
if(random.includes(array[i])){
random.splice(random.indexOf(array[i]), 1)
}
}
}
remove([10, 12, 30]);
console.log(random); // [4, 15]
I am assuming you want to remove because if you already know which elements you want why filter them out? why not just pass them into your function as a new array? filter will create a new array anyways.
But if you would like to remove elements from your first array the answer above might help.
This question already has answers here:
Split array into chunks
(73 answers)
Closed 5 years ago.
Assuming I have an integer n which is greater than 0, and an array like this:
var array = [1, 2, 5, 6, 8, 9, 12, 13, 17...] //random values
How would I iterate through this array, going through and getting values n at a time (and putting it into a 2D array as well)?
If n were 3, for example, I would want a return value of
[[1, 2, 5], [6, 8, 9], [12, 13, 17]...]
And the code would be like this:
var array = [];
for (var i = 0; i < array.length; i += 3) {
var first = array[i];
var second = array[i+1];
var third = array[i+2];
array.push([
first, second, third
]);
}
Problem with this is that I have fixed values to get my objects by (the i, i+1, etc.)
If I have an unknown integer, then incrementing right up to n will not work.
How would I go about achieving this?
Use slice to take chunks and go through the array:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const partition = (n, arr) => {
const result = [];
let i = 0;
while(i < arr.length) {
result.push(arr.slice(i, i + n));
i = i + n;
}
return result;
};
console.log(partition(1, arr));
console.log(partition(2, arr));
console.log(partition(3, arr));
console.log(partition(4, arr));
pretty new to Javascript and I've tried this question about 4 times now in a span of about a month and I am still unable to solve it.
So here is the question:
Construct a function intersection that compares input arrays and returns a new array with elements found in all of the inputs. BONUS: Use reduce!
The format is:
function intersection(arrays) {
// Your Code Goes Here
}
Test Case: Should log [15, 5]
console.log('Extensions 3 Test: ' + intersection([5, 10, 15, 20], [15, 88, 1, 5, 7]/*, [1, 10, 15, 5, 20]*/));
My current solution: Works for the case of only have two items to compare, but not for the third one, I could make it so that I would loop through and compare the obtained values with the next array but I don't think I am on the right path... Also, I am not using reduce to implement it... And I am not sure if I am supposed to be using 'arguments.' Any help is appreciated! Thank you so much.
function intersection(arrays) {
array = [];
for (var i = 0; i < arguments.length; i++)
array.push(arguments[i]);
var result = [];
for(var i = 0; i < array.length - 1; i++) {
for(var j = 0; j < array[i].length; j++) {
if (array[i+1].includes(array[i][j]))
result.push(array[i][j]);
}
}
return result;
}
Although, as several suggestions said, you could use underscore, lodash, or my personal favorite, Ramda (disclaimer: I'm one of the authors), this function should be straightforward enough that you wouldn't even consider a library for it. Here's a simple version:
const intersection = (xs, ys) => xs.filter(x => ys.indexOf(x) > -1);
intersection([5, 10, 15, 20, 3], [15, 88, 3, 1, 5, 7]); //=> [5, 15, 3]
const intersectAll = (...xss) => xss.reduce(intersection);
intersectAll([5, 10, 15, 20, 3], [15, 88, 3, 1, 5, 7], [1, 10, 15, 5, 20]); //=> [5, 15]
I would think that this is all you need, at least so long as you're worried only about reference/primitive equality and don't need to consider cases where you want to know that {x: 1} and {x: 1} are the same, even though they aren't the same reference. If you do need that, you might look to Ramda's intersection function.
Note that if includes were better supported, I would recommend this version instead, as it reads better:
const intersection = (xs, ys) => xs.filter(x => ys.includes(x));
Also, if you have no need for the binary function, you can make just a variadic version of it by combining the two above:
const intersection = (...xss) => xss.reduce((xs, ys) => xs.filter(x => ys.indexOf(x) > -1));
Maybe someone will finds it useful.
As an argument to the function you can give any number of arrays of any length and the function is compact, I think ;)
const findSimilar = (...arrays) => {
return arrays.reduce((includ, current) =>
Array.from(new Set(includ.filter((a) => current.includes(a))))
);
};
console.log(
findSimilar([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20])
);
And how it works:
Ok, first u take rest parameters(...arrays) as parameter of function, so u have
arrays = [ [5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20] ]
then in first iteration of reduce we have
includ = [5, 10, 15, 20] and current = [15, 88, 1, 5, 7]
on this two we use filter, what give us [5,15], i use Set to make shure there is no repetition and make array back (Array.from()), which is passed to the next iteration of reduce as "includ", at the next iteration we have
incude = [5,15] and current = [1, 10, 15, 5, 20] and so on ...
We can even use it like this
let result = [
[5, 10, 15, 20],
[15, 88, 1, 5, 7],
[1, 10, 15, 5, 20]
].reduce((includ, current) =>
Array.from(new Set(includ.filter((a) => current.includes(a))))
);
console.log(result);
Although not solving your problem directly, you can do what you're trying to do using the opensource library underscore.js.
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]
You may be able to derive inspiration from the way that's been implemented. The above is the function call to their own _.intersection function which is also dependent on other underscore.js functions as you see below:
// Produce an array that contains every item shared between all the
// passed-in arrays.
_.intersection = function(array) {
if (array == null) return [];
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = array.length; i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
Here is a solution using reduce, with the empty array passed in as intersection as the initial value.
Iterate the numbers and check if each one appears in one of the subarrays.
If it doesn't, set the Boolean isPresentInAll to false.
If it does appear in all three and it's not already present in the
intersection array, then push to the intersection array.
function intersection(arrayOfArrays) {
return arrayOfArrays.reduce(function(intersection, subArray) {
subArray.forEach(function(number) {
var isPresentInAll = true;
for (var i = 0; i < arrayOfArrays.length; i++) {
if (arrayOfArrays[i].indexOf(number) === -1) {
isPresentInAll = false;
}
}
if (isPresentInAll === true && intersection.indexOf(number) === -1) {
intersection.push(number);
}
});
return intersection;
}, []);
}
I think i got the right function for you.
(Note: results are not sorted!)
var intersection = function() {
// merge deduped arrays from arguments
var arrays = Array.prototype.reduce.call(arguments, function(carry, array) {
return [].concat(carry, array.filter(function(item, index, origin) {
return origin.indexOf(item) === index;
}));
}, []);
var results = arrays.reduce(function(carry, item, index, arr) {
if(
// just select items, which have more then 1 occurance
arr.filter(function(fItem) {
return fItem === item;
}).length > 1 &&
// ... and which are not already in results
!~carry.indexOf(item)
) {
carry = [].concat(carry,item);
}
return carry;
}, []);
return results;
};
Here's a version that uses 2 reduces.
The first iterates the arrays only once to create a hashmap object to track instance counts, the second to return values where counts match number of arguments
function intersection(){
// convert arguments to array of arrays
var arrays = [].slice.call(arguments);
// create an object that tracks counts of instances and is type specific
// so numbers and strings would not be counted as same
var counts= arrays.reduce(function(a,c){
// iterate sub array and count element instances
c.forEach(function(val){
var propName = typeof val + '|' + val;
// if array value not previously encountered add a new property
a[propName] = a[propName] || {count:0, value: val};
// increment count for that property
a[propName].count++;
});
return a;
},{});
// iterate above object to return array of values where count matches total arrays length
return Object.keys(counts).reduce(function(resArr, propName){
if(counts[propName].count === arrays.length){
resArr.push(counts[propName].value);
}
return resArr;
},[]);
}
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]))
Could use some fine tuning to make sure there are enough arguments and that they are all arrays
Here's what I came up with using vanilla javascript and one call to reduce.
function intersection(){
var arrays = [].slice.call(arguments);
var first = arrays[0];
var rest = arrays.slice(1);
return first.reduce(function(all, item, index){
var push = rest.every(function(subArray){
return subArray.indexOf(item) > -1;
});
if(push){
all.push(item);
}
return all;
},[])
}
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
function intersection(arrays) {
let common = arrays.reduce(function(accumulator, currentValue) {
return accumulator.filter(function(x){
return currentValue.indexOf(x) > -1;
})
})
return common;
}
To optimize your answer that couldn't work on more than 2 subarrays and didn't use reduce, here's the code that works for however many subarrays you pass in.
function intersection(arr1, arr2, arr3){
let ans = arr1[0]; // ans = [5,10,15,20]
for(let i = 0; i < ans.length; i++){ // i = 0...3
for(let j = 1; j < arr1.length; j++){ // j = 1...2
if(!(arr1[j].includes(ans[i]))){ // if the new subarray doesn't include an element in the ans
ans.splice(i, 1); // delete the element from ans
}
}
}
return ans;
}
const arr1 = [5, 10, 15, 20];
const arr2 = [15, 88, 1, 5, 7];
const arr3 = [1, 10, 15, 5, 20];
console.log(intersection([arr1, arr2, arr3])); // should log: [5, 15]
I am trying to interchange array and print it using shift method but not sure whether I can use it or not.
Code Snippet below.
var points = [40, 100, 1, 5, 25, 10];
//trying to achieve like anotherPoints array
//var anotherPoints = [1, 5, 100, 40, 25, 10];
for (index = 0; index < points.length; index++) {
points.shift();
console.log(points);
}
Some logic to get the desired result:
var points = [40, 100, 1, 5, 25, 10],
temp1 = [], temp2 = [], anotherArray;
points.forEach(function(val){
if(val < 10 ) {
temp1.push(val)
} else {
temp2.push(val);
}
});
anotherArray = temp1.sort().concat(temp2.sort(function(a,b){return b- a}));
alert(anotherArray);
It's not possible via shift or splice. Unless manually creating the array.
The shift() method doesn't shift or interchange the elements of an Array. It is similar to pop(), but it pops out the first element from the Array.
For example,
var points = [40, 100, 1, 5, 25, 10];
console.log(points.shift()); // 40
console.log(points); // [100, 1, 5, 25, 10]
As to your requirement of rearranging the elements of an Array, you will have to use Array.splice() method. Check out this question Reordering arrays.