Related
I have two arrays:
a = [2,2,3,0,6]
b = [6,3,2,2,0]
I am trying use for loop to match values and get the index of a in a new array c. How can we do this? Notice that there are multiple values which match and so I think the previous match must be skipped.
This is a proposal which respects the last index and looks further.
How it works:
It uses Array#map for iterating array b with a callback. map gets an own this space with an really empty object Object.create(null).
The callback has on parameter bb which is one element of `b.
Next is to find the element is in array a with a Array#indexOf and a fromIndex, based on the former searches. The former index is stored in the this object, as long as the result is not -1, because this would reset the fromIndex to zero.
If there is no this[bb] or a falsy value of this[bb] take zero as fromIndex.
Later, a found index is incremented and stored in this[bb].
At least, the index is returned.
var a = [2, 2, 3, 0, 6],
b = [6, 3, 2, 2, 0],
c = b.map(function (bb) {
var index = a.indexOf(bb, this[bb] || 0);
if (index !== -1) {
this[bb] = index + 1;
}
return index;
}, Object.create(null));
console.log(c);
Another solution could be first generate an object with all indices of a and use it in the iteration of b for returning the indices.
The example is a bit extended, to show what happen if there is no more than two indices (2) and one without being in a (7).
The content of aObj with all indices of a:
{
"0": [3],
"2": [0, 1],
"3": [2],
"6": [4]
}
var a = [2, 2, 3, 0, 6],
b = [6, 3, 2, 2, 0, 7, 2],
aObj = Object.create(null),
c;
a.forEach(function (aa, i) {
aObj[aa] = aObj[aa] || [];
aObj[aa].push(i);
});
c = b.map(function (bb) {
return aObj[bb] && aObj[bb].length ? aObj[bb].shift() : -1;
});
console.log(c);
As far I Understand, You can try this:
var a = [2,2,3,0,6];
var b = [6,3,2,2,0];
var c = new Array();
for(i = 0; i < b.length; i++)
{
for(j = 0; j < a.length; j++)
{
if(b[i] === a[j] && c.indexOf(j) < 0)
{
c.push(j);
break;
}
}
}
console.log(c); // [4, 2, 0, 1, 3]
FIDDLE DEMO HERE
If I understand correct.
let c = a.map(i => b.indexOf(i))
or
var c = a.map(function(i) { return b.indexOf(i); });
loop .map function and check same value by indexOf
indexOf will return a number,representing the position where the specified search value occurs for the first time, or -1 if it never occurs
var arr = [];
a.map(function(v){
if(b.indexOf(v) > -1){
arr.push(v);
}
});
console.log(arr);
try something like this
var a = [2,2,3,0,6];
var b = [6,3,2,2,0];
var arrayLength_a = a.length;
var arrayLength_b = b.length;
var new_array=[];
for (var i = 0; i < arrayLength_a; i++)
{
for (var j = 0; j < arrayLength_b; j++)
{
if (a[i] == b[j])
{
if(new_array.indexOf(a[i]) === -1)
{
new_array.push(a[i]);
}
}
}
}
I have 10 different arrays. Each array has different numbers.
array1 = [1,2,3,4,5]
array2 = [6,7,8,9,10]
...
array 10 = [51,52,53,54]
let's say I pass in 7. Then I want to know which array it is from and want to return array number. So in this case it is going to be 2.
Should I write a switch statement for each array? Appreciate it in javascript.
try:
var arrays = [array1, array2, ..., array10];
for(var i=0; i<arrays.length; ++i) {
if (arrays[i].indexOf(value) != -1) {
console.log('found in array' + (i+1));
}
}
You cannot directly retrieve the name of array.The reason is this variable is only storing a reference to the object.
Instead you can have a key inside the same array which represent its name. Then indexOf can be used to find the array which contain the number , & if it is so, then get the array name
var array1 = [1,2,3,4,5];
array1.name ="array1";
var array2 = [6,7,8,9,10];
array2.name ="array2";
var array10 = [51,52,53,54]
array10.name ="array10";
var parArray = [array1,array2,array10]
function _getArrayName(number){
for(var o=0;o<parArray.length;o++){
var _tem = parArray[o];
if(parArray[o].indexOf(number) !==-1){
console.log(parArray[o].name);
}
}
}
_getArrayName(6) //prints array2
jsfiddle
One fast method should be using hash tables or as i would like to call LUT. Accordingly this job boils down to a single liner as follows;
var arrs = {
arr1 : [1,2,3,4,5],
arr2 : [6,7,8,9,10],
arr3 : [12,14,16,17],
arr4 : [21,23,24,25,27,20],
arr5 : [31,34,35,39],
arr6 : [45,46,44],
arr7 : [58,59],
arr8 : [66,67,69,61],
arr9 : [72,73,75,79,71],
arr0 : [81,85,98,99,90,80]
},
lut = Object.keys(arrs).reduce((p,c) => {arrs[c].forEach(n => p[n]=c); return p},{}),
findar = n => lut[n];
document.write("<pre>" + findar(12) + "</pre>");
One way to do this is have the arrays in an object and iterate over the keys/values. This method doesn't presume the arrays (and therefore their names) are in sequential order.
Note: this will always return a the first match from the function and terminate the search.
var obj = {
array1: [1, 2, 3, 4, 5],
array2: [6, 7, 8, 9, 10],
array3: [51, 52, 53, 54],
array4: [51, 52, 53, 54, 7]
}
function finder(obj, test) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
return key.match(/\d+/)[0];
}
}
return false;
}
finder(obj, 7); // '2'
DEMO
If you want to find all instances of a value in all arrays the function needs to be altered slightly.
function finder(obj, test) {
var keys = Object.keys(obj);
var out = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
out.push(key.match(/\d+/)[0]);
}
}
return out;
}
finder(obj, 7); // ['2', '4']
DEMO
I encountered a problem!
for example! here is my 2 dimensional array: var array=[[1,2,3,4],[2,3,4,5],[3,4,5,6]];
and my desired outcome is : [[1,2,3,4],[2,3,4,5],[3,4,5,6],[6,9,12,15]]
the [6,9,12,15] came from adding the same index numbers of the previous inner arrays. (ex 1+2+3, 2+3+4, 3+4+5, 4+5+6 more clear : index 1 + index 1+ index1 produces 9)
I am so confused so far, the closes i did was to sum up [1,2,3,4][2,3,4,5][3,4,5,6], but I cant seem to do something with each and individual numbers :(
The question requested me to do nested for loops, So i cant use any thing like reduce, map, flatten, etc...
try with this way:https://jsfiddle.net/0L0h7cat/
var array=[[1,2,3,4],[2,3,4,5],[3,4,5,6]];
var array4 = [];
for (j = 0; j < array[0].length; j++) {
var num =0;
for(i=0;i< array.length;i++){
num += array[i][j];
}
array4.push(num);
}
array.push(array4);
alert(array);
Just iterate over the outer array and the inner arrays and add the values to the result array array[3].
var array = [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]];
array.forEach(function (a) {
a.forEach(function (b, i) {
array[3] = array[3] || [];
array[3][i] = (array[3][i] || 0) + b;
});
});
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');
https://jsfiddle.net/0L0h7cat/
var array = [
[1, 2, 3, 4],
[2, 3, 4, 5],
[3, 4, 5, 6]
];
var sumArr = [];
for (var i = 0; i < array[0].length; i++) {
sumArr[i] = 0;
for (var j = 0; j < array.length; j++)
sumArr[i] += array[j][i];
}
array.push(sumArr);
If you are interested in Arrow Functions, this will work:-
var array = [[1, 2, 3, 4],[2, 3, 4, 5],[3, 4, 5, 6]];
var count = [];
array.forEach(x => x.forEach((y, i) => count[i] = (count[i] || 0) + y));
array.push(count);
console.log(array);
NOTE: Not cross browser support yet.
This is how -
var array=[[1,2,3,4],[2,3,4,5],[3,4,5,6]];
var array2=[]
for (var i = array[0].length;i--;) {
var sum=0;
for (var j = array.length; j--;) {
sum=sum+array[j][i];
}
array2.push(sum)
}
array.push(array2.reverse());
document.write('<pre>'+JSON.stringify(array) + '</pre>');
But I'm sure there are more elegant methods. I'm just learning by answering questions myself.
A simplistic approach with just conventional for loops
var input = [[1,2,3,4],[2,3,4,5],[3,4,5,6]];
function getSumOfArrayOfArrays(inputArray) {
var length = inputArray.length;
var result = [];
for(var i=0; i<length; i++){
for(var j=0; j<=3; j++){
result[j] = result[j] ? result[j] + inputArray[i][j] : inputArray[i][j];
}
}
return result;
}
var output = getSumOfArrayOfArrays(input); // [6,9,12,15]
var desiredOutput = input;
desiredOutput.push(output)
document.write(JSON.stringify(desiredOutput));
// [[1,2,3,4],[2,3,4,5],[3,4,5,6],[6,9,12,15]]
I try to avoid writing nested for loops.
var arrayOfArrays=[
[1,2,3,4],
[2,3,4,5],
[3,4,5,6]
];
//define a function to extend the Array prototype
Array.prototype.add = function(otherArray){
var result = [];
for(var i = 0; i < this.length; i++) {
result.push( this[i] + otherArray[i] )
}
return result;
};
//reduce array of arrays to get the result array `sum`
var sum = arrayOfArrays.reduce(function(arrayA, arrayB){
//`arrayA`+`arrayB` becomes another `arrayA`
return arrayA.add(arrayB)
});
//put `sum` back to `arrayOfArrays`
arrayOfArrays.push(sum);
document.write('<pre>' + JSON.stringify(arrayOfArrays) + '</pre>');
Let’s assume we have this two arrays:
x = [1, 2, 3];
y = ['a', 'b'];
What would be the best way to combine them and get the following result:
newArray = ['1a', '1b', '2a', '2b', '3a', '3b'];
Here is one way of doing that:
x.reduce(function(arr, x) {
return arr.concat(y.map(function(y) {
return x + y;
}));
}, []);
//=> ["1a", "1b", "2a", "2b", "3a", "3b"]
Try this:
var x = [1, 2, 3];
var y = ['a', 'b'];
var output = [];
for (var i = 0; i < x.length; i++) {
for (var j = 0; j < y.length; j++) {
output.push(x[i]+y[j]);
}
}
document.getElementById('output').innerHTML = JSON.stringify(output);
<div id="output"></div>
Try this..
var x = [1, 2, 3];
var y = ['a', 'b'];
var newarr = [];
for(var i=0;i<x.length;i++){
for(var j=0;j<y.length;j++){
newarr.push(x[i]+y[j]);
}
}
//alert(newarr);
DEMO
If arrow functions are supported you obtain the desired result like this:
[].concat.apply([],
x.map(x => y.map(y => x+y))
);
If not, you have to write it like this
[].concat.apply([],
x.map(function(x) { return y.map(function(y) {return x+y })})
);
Explanation:
The middle line yields the following result:
[ ["1a", "1b"], ["2a", "2b"], ["3a", "3b"] ]
Then the Array.prototype.concat method is used to concatenate the inner arrays.
You could simply create a array to be returned and do a simple loop for the array that contains numbers. Inside of that loop, you create another loop for the array of combinations to the numbers (var b=0,e=comb.length;e>b;b++). Using the i from the first loop (for(var i=0,l=array.length;l>i;i++)) you push the array at it (a[i]) with the array of combinations at the position b (c[b]) (inside of the loop that's inside of the first loop) to the new array. Finally, return the new array.
function CombineExample(a,c){
var New=[];
for(var i=0,l=a.length;l>i;i++){
for(var b=0,e=c.length;e>b;b++){
New.push(a[i]+c[b])
}
}
return New
}
Clean! And do this to use:
CombineExample([1,2,3],['a','b'])
/* returns ["1a", "1b", "2a", "2b", "3a", "3b"] */
Use nested loops to iterate all elements of the participating arrays. Populate new array elements inside the inner loop:
var x = [1, 2, 3];
var y = ['a', 'b'];
var newArray = [];
x.forEach(function(xItem) {
y.forEach(function(yItem) {
newArray.push(xItem.toString().concat(yItem));
});
});
console.log(newArray);
The simplest approach:
var x = ["a", "b", "c"];
var y = [1, 2, 3];
var newArray = [];
var i = 0;
for (;i < x.length;++i) {
var j = 0;
for (;j < y.length;++j) {
newArray.push(x[i] + y[j]);
}
}
;
Please do note that if both arrays are numeric, this will actually add the numbers, not concatenate. You'd need to do some string conversion.
var x = [1, 2, 3];
var y = ['a', 'b'];
var z = [];
for(var i=0;i<x.length;i++){
for(var j=0;j<y.length;j++){
z.push(x[i]+y[j]);
}
}
Are you seriously asking for that?
I am saving some data in order using arrays, and I want to add a function that the user can reverse the list. I can't think of any possible method, so if anybody knows how, please help.
Javascript has a reverse() method that you can call in an array
var a = [3,5,7,8];
a.reverse(); // 8 7 5 3
Not sure if that's what you mean by 'libraries you can't use', I'm guessing something to do with practice. If that's the case, you can implement your own version of .reverse()
function reverseArr(input) {
var ret = new Array;
for(var i = input.length-1; i >= 0; i--) {
ret.push(input[i]);
}
return ret;
}
var a = [3,5,7,8]
var b = reverseArr(a);
Do note that the built-in .reverse() method operates on the original array, thus you don't need to reassign a.
Array.prototype.reverse() is all you need to do this work. See compatibility table.
var myArray = [20, 40, 80, 100];
var revMyArr = [].concat(myArray).reverse();
console.log(revMyArr);
// [100, 80, 40, 20]
Heres a functional way to do it.
const array = [1,2,3,4,5,6,"taco"];
function reverse(array){
return array.map((item,idx) => array[array.length-1-idx])
}
20 bytes
let reverse=a=>[...a].map(a.pop,a)
const original = [1, 2, 3, 4];
const reversed = [...original].reverse(); // 4 3 2 1
Concise and leaves the original unchanged.
reveresed = [...array].reverse()
The shortest reverse method I've seen is this one:
let reverse = a=>a.sort(a=>1)
**
Shortest reverse array method without using reverse method:
**
var a = [0, 1, 4, 1, 3, 9, 3, 7, 8544, 4, 2, 1, 2, 3];
a.map(a.pop,[...a]);
// returns [3, 2, 1, 2, 4, 8544, 7, 3, 9, 3, 1, 4, 1, 0]
a.pop method takes an last element off and puts upfront with spread operator ()
MDN links for reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop
two ways:
counter loop
function reverseArray(a) {
var rA = []
for (var i = a.length; i > 0; i--) {
rA.push(a[i - 1])
}
return rA;
}
Using .reverse()
function reverseArray(a) {
return a.reverse()
}
This is what you want:
array.reverse();
DEMO
Here is a version which does not require temp array.
function inplaceReverse(arr) {
var i = 0;
while (i < arr.length - 1) {
arr.splice(i, 0, arr.pop());
i++;
}
return arr;
}
// Useage:
var arr = [1, 2, 3];
console.log(inplaceReverse(arr)); // [3, 2, 1]
I've made some test of solutions that not only reverse array but also makes its copy. Here is test code. The reverse2 method is the fastest one in Chrome but in Firefox the reverse method is the fastest.
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var reverse1 = function() {
var reversed = array.slice().reverse();
};
var reverse2 = function() {
var reversed = [];
for (var i = array.length - 1; i >= 0; i--) {
reversed.push(array[i]);
}
};
var reverse3 = function() {
var reversed = [];
array.forEach(function(v) {
reversed.unshift(v);
});
};
console.time('reverse1');
for (var x = 0; x < 1000000; x++) {
reverse1();
}
console.timeEnd('reverse1'); // Around 184ms on my computer in Chrome
console.time('reverse2');
for (var x = 0; x < 1000000; x++) {
reverse2();
}
console.timeEnd('reverse2'); // Around 78ms on my computer in Chrome
console.time('reverse3');
for (var x = 0; x < 1000000; x++) {
reverse3();
}
console.timeEnd('reverse3'); // Around 1114ms on my computer in Chrome
53 bytes
function reverse(a){
for(i=0,j=a.length-1;i<j;)a[i]=a[j]+(a[j--]=a[i++],0)
}
Just for fun, here's an alternative implementation that is faster than the native .reverse method.
You can do
var yourArray = ["first", "second", "third", "...", "etc"]
var reverseArray = yourArray.slice().reverse()
console.log(reverseArray)
You will get
["etc", "...", "third", "second", "first"]
> var arr = [1,2,3,4,5,6];
> arr.reverse();
[6, 5, 4, 3, 2, 1]
array.reverse()
Above will reverse your array but modifying the original.
If you don't want to modify the original array then you can do this:
var arrayOne = [1,2,3,4,5];
var reverse = function(array){
var arrayOne = array
var array2 = [];
for (var i = arrayOne.length-1; i >= 0; i--){
array2.push(arrayOne[i])
}
return array2
}
reverse(arrayOne)
function reverseArray(arr) {
let reversed = [];
for (i = 0; i < arr.length; i++) {
reversed.push((arr[arr.length-1-i]))
}
return reversed;
}
Using .pop() method and while loop.
var original = [1,2,3,4];
var reverse = [];
while(original.length){
reverse.push(original.pop());
}
Output: [4,3,2,1]
I'm not sure what is meant by libraries, but here are the best ways I can think of:
// return a new array with .map()
const ReverseArray1 = (array) => {
let len = array.length - 1;
return array.map(() => array[len--]);
}
console.log(ReverseArray1([1,2,3,4,5])) //[5,4,3,2,1]
// initialize and return a new array
const ReverseArray2 = (array) => {
const newArray = [];
let len = array.length;
while (len--) {
newArray.push(array[len]);
}
return newArray;
}
console.log(ReverseArray2([1,2,3,4,5]))//[5,4,3,2,1]
// use swapping and return original array
const ReverseArray3 = (array) => {
let i = 0;
let j = array.length - 1;
while (i < j) {
const swap = array[i];
array[i++] = array[j];
array[j--] = swap;
}
return array;
}
console.log(ReverseArray3([1,2,3,4,5]))//[5,4,3,2,1]
// use .pop() and .length
const ReverseArray4 = (array) => {
const newArray = [];
while (array.length) {
newArray.push(array.pop());
}
return newArray;
}
console.log(ReverseArray4([1,2,3,4,5]))//[5,4,3,2,1]
As others mentioned, you can use .reverse() on the array object.
However if you care about preserving the original object, you may use reduce instead:
const original = ['a', 'b', 'c'];
const reversed = original.reduce( (a, b) => [b].concat(a) );
// ^
// |
// +-- prepend b to previous accumulation
// original: ['a', 'b', 'c'];
// reversed: ['c', 'b', 'a'];
Pure functions to reverse an array using functional programming:
var a = [3,5,7,8];
// ES2015
function immutableReverse(arr) {
return [ ...a ].reverse();
}
// ES5
function immutableReverse(arr) {
return a.concat().reverse()
}
It can also be achieved using map method.
[1, 2, 3].map((value, index, arr) => arr[arr.length - index - 1])); // [3, 2, 1]
Or using reduce (little longer approach)
[1, 2, 3].reduce((acc, curr, index, arr) => {
acc[arr.length - index - 1] = curr;
return acc;
}, []);
reverse in place with variable swapping (mutative)
const myArr = ["a", "b", "c", "d"];
for (let i = 0; i < (myArr.length - 1) / 2; i++) {
const lastIndex = myArr.length - 1 - i;
[myArr[i], myArr[lastIndex]] = [myArr[lastIndex], myArr[i]]
}
Reverse by using the sort method
This is a much more succinct method.
const resultN = document.querySelector('.resultN');
const resultL = document.querySelector('.resultL');
const dataNum = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const dataLetters = ['a', 'b', 'c', 'd', 'e'];
const revBySort = (array) => array.sort((a, b) => a < b);
resultN.innerHTML = revBySort(dataNum);
resultL.innerHTML = revBySort(dataLetters);
<div class="resultN"></div>
<div class="resultL"></div>
Using ES6 rest operator and arrow function.
const reverse = ([x, ...s]) => x ? [...reverse(s), x] : [];
reverse([1,2,3,4,5]) //[5, 4, 3, 2, 1]
Use swapping and return the original array.
const reverseString = (s) => {
let start = 0, end = s.length - 1;
while (start < end) {
[s[start], s[end]] = [s[end], s[start]]; // swap
start++, end--;
}
return s;
};
console.log(reverseString(["s", "t", "r", "e", "s", "s", "e", "d"]));
Infact the reverse() may not work in some cases, so you have to make an affectation first as the following
let a = [1, 2, 3, 4];
console.log(a); // [1,2,3,4]
a = a.reverse();
console.log(a); // [4,3,2,1]
or use concat
let a = [1, 2, 3, 4];
console.log(a, a.concat([]).reverse()); // [1,2,3,4], [4,3,2,1]
What about without using push() !
Solution using XOR !
var myARray = [1,2,3,4,5,6,7,8];
function rver(x){
var l = x.length;
for(var i=0; i<Math.floor(l/2); i++){
var a = x[i];
var b = x[l-1-i];
a = a^b;
b = b^a;
a = a^b;
x[i] = a;
x[l-1-i] = b;
}
return x;
}
console.log(rver(myARray));
JavaScript already has reverse() method on Array, so you don't need to do that much!
Imagine you have the array below:
var arr = [1, 2, 3, 4, 5];
Now simply just do this:
arr.reverse();
and you get this as the result:
[5, 4, 3, 2, 1];
But this basically change the original array, you can write a function and use it to return a new array instead, something like this:
function reverse(arr) {
var i = arr.length, reversed = [];
while(i) {
i--;
reversed.push(arr[i]);
}
return reversed;
}
Or simply chaning JavaScript built-in methods for Array like this:
function reverse(arr) {
return arr.slice().reverse();
}
and you can call it like this:
reverse(arr); //return [5, 4, 3, 2, 1];
Just as mentioned, the main difference is in the second way, you don't touch the original array...
How about this?:
function reverse(arr) {
function doReverse(a, left, right) {
if (left >= right) {
return a;
}
const temp = a[left];
a[left] = a[right];
a[right] = temp;
left++;
right--;
return doReverse(a, left, right);
}
return doReverse(arr, 0, arr.length - 1);
}
console.log(reverse([1,2,3,4]));
https://jsfiddle.net/ygpnt593/8/