I am trying to write a function that performs operations on an array and returns a different copy of the array and leaves the original one unchanged. I thought I could do this by declaring var array2 = array and then proceeding with the array operations. What am I doing wrong?
Here is my sample function:
var partition = function(array, p){
var pivot = array[p];
var length = array.length;
// make a copy and move pivot to the front
var array2 = array;
array2[p] = array2[0];
array2[0] = pivot;
// partition the array
var i = 1;
for (var j = 1; j < length; j++){
//console.log('i='+i+', j='+j)
if (array2[j] < pivot) {
var temp = array2[j];
array2[j] = array2[i];
array2[i] = temp;
i++;
}
}
//console.log('array after partitioning: ' + array)
// swap pivot
array2[0] = array2[i-1];
array2[i-1] = pivot;
var answer = {array: array2, p: i-1}
return answer;
};
And my sample call:
var a = [3, 2, 1];
partition(a, 0);
console.log(a); // prints [1,2,3] but I want [3,2,1]
add this line instead of array2=array because it's only create a reference to array not the new array2.
var array2 =array.slice(0); //it will create a new array not the reference.
Fiddle http://jsfiddle.net/N64w3/
var array2 = array.slice(0) or just array.slice() will clone your array
Here you have reference to that
Related
I am trying to push numbers in an array into another array in groups of two.
If I have an array [1,4,3,2]; it should return [[1,4],[3,2]];
var arrayPairSum = function(nums) {
var len = nums.length / 2;
var arr = [];
for(var i = 0; i < len; i ++) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1,4,3,2]);
can anyone see what I need to do to achieve this? I cannot figure it out.
You can use reduce method to achieve this. reduce method accepts a callback method provided on every item in the array.
In the other words, this method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
var array=[1,4,3,2,8];
var contor=array.reduce(function(contor,item,i){
if(i%2==0)
contor.push([array[i],array[i+1]].filter(Boolean));
return contor;
},[]);
console.log(contor);
If you really want to iterate over the array, may skip every second index, so i+=2 ( as satpal already pointed out) :
var arrayPairSum = function(nums) {
var len = nums.length - 1;//if nums.length is not even, it would crash as youre doing nums[i+1], so thats why -1
var arr = [];
for (var i = 0; i < len; i += 2) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1, 4, 3, 2]);
The upper one crops away every non pair at the end. If you want a single [value] at the end, may go with
len=nums.length
And check later before pushing
if(i+1<nums.length) newArr.push(nums[i+1]);
You were pretty close. Simply change the length to nums.length and in the loop increment i by 2.
var arrayPairSum = function(nums) {
var len = nums.length - 1;
var arr = [];
for(var i = 0; i < len; i+=2) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1,4,3,2]);
If I have two immutable lists,
const a = [1,2,3];
const b = [a,b,c,d];
is there an easy way to merge/zip them to result in:
const c = [1,a,2,b,3,c,d];
Is interleave what you are looking for: https://facebook.github.io/immutable-js/docs/#/List/interleave
const a = List([1, 2, 3]);
const b = List([a, b, c, d]);
a.interleave(b)
const a = [1, 2, 3] don't make this array immutable at all. What const does is to guarantee that you're not reassigning a. Pushing or removing items to a don't constitute a reassignment.
This is a real immutable list using immutable.js:
const a = List([1, 2, 3]);
Now.. back to zip.
If you don't want another reference, you can just use a for in the smallest list and build the zip yourself. If you want a ready-made function, you might consider using Underscore's Zip, which does exactly what you want.
If you want to develop a function from scratch then you can use the code below. Basically, the function merges the two array as interleaving the two. Consider 2 arrays, array1 = [1,2,3,4] and array2 = [a,b,c,d,e,f]. Then the below code will output a new array [1,a,2,b,3,c,4,d,e,f]
var i = 0;
var j = 0;
var k = 0;
var len1 = array1.length;
var len2 = array2.length;
var flag = true;
var newArr = [];
//Merge the 2 arrays till the smaller sized array
while (i < len1 && j < len2)
{
if(flag){
newArr[k] = array1[i];
i++; k++;
flag = false;
}
else{
newArr[k] = array2[j];
j++; k++;
flag = true;
}
}
/* Copy the remaining elements of array1[], if there are any */
while (i < len1)
{
newArr[k] = array1[i];
i++;
k++;
}
/* Copy the remaining elements of array2[], if there are any */
while (j < len2)
{
newArr[k] = array2[j];
j++;
k++;
}
console.log(newArr)
I have an array and an array of objects. I want to search each value in the array in the array of objects and if it doesnt exist, I want to remove the value from the array.
var arr= [1,2,3,4];
var recs = [{id:1},{id:2},{id:3}]; //4 doesnt exist in recs, remove from arr
//arr = [1,2,3];
Heres my attempt. Obviously does not work. I am not sure how I can compare each arr index with all the values in recs before moving on the next arr index:
var arr= [1, 2, 3, 4], index;
var recs = [{a:1},{a:2},{a:3}];
for(var i = 0; i<arr.length; i++){
for(var val in recs[i]){
if(arr[i] != recs[i][val]){
index = arr.indexOf(arr[i]);
arr.splice(index, 1);
}
}
}
thank you!!
If you are okay with leaving your original array instance alone and creating a new one (essentially treating it as immutable)
var newArr = arr.filter(function(num) {
return !recs.every(function(obj) {
return obj.a !== num;
});
});
Detail of the methods used: Array.filter is passed a function, runs that function on each element inside, and then returns a new array with only the elements that returned true in the function.
Array.every works a little similar, but returns a Boolean, true or false. It returns true if all of the elements of the array returned true inside of the function.
var arr= [1, 2, 3, 4];
var recs = [{a:1},{a:2},{a:3}];
// don't use var in for loops.
// Variables declared with var have function scope, so declare them at the top of your function
var i;
var j;
var value;
var found;
// iterate over the array
for (i = 0; i < arr.length; i++)
{
value = arr[i];
found = false;
// iterate over the other array
for (j = 0 ; j < recs.length ; j++)
{
// if we found what we were looking for, make a note and exit loop
if (recs[j].a == value)
{
found = true;
break;
}
}
if (!found)
{
arr.splice(i, 1);
// To compensate the loop's i++, to avoid skipping the next entry
i--;
}
}
alert(arr.join(','));
I am trying to rearrange elements in an array of arrays but have been unsucessful. Can anyone offer suggestions? Here are two options I have tried. I want to swap/switch places for the first and second elements.
arr1 is an array of arrays (i.e. arr[][]) so I created arr2 to be an updated arr1
var arr2 = [];
for (var n = 0; n <arr1.length; n++){
arr2[n][0] = arr1[n][1];
arr2[n][1] = arr1[n][0];
}
The other thing I tried was:
function order(arr[]){
return [arr[n][1],arr[n][0], arr[n][2], arr[n][3]];
}
var arr2 = order(arr1);
You also need to create a new array for each item:
var arr2 = [];
for(var n = 0; n < arr1.length; n++) {
arr2[n] = [arr1[n][1], arr1[n][0]];
}
it's quite easy:
var a = arr1[n][0];
arr2[n][0] = arr1[n][1];
arr2[n][1] = a;
you need to save the first value as a variable, because if you do as you did(arr2[n][0] = arr1[n][1];), your two array indexes will have the same value.
You did:
a = 1, b = 2;
a = b;
b = a;
Which resolves in a = 2, b = 2
Also, your code as it is now, doesn't work. You need to create a new array for the simulation of multidimensional arrays in javascript.
for(i = 0; i < (yourdesiredamountofarrays); i++)
{
yourarray[i] = new Array();
}
The first example you need to use a temporary variable for the switch:
var arr2 = [];
for (var n = 0; n <arr1.length; n++){
var tempVal = arr1[n][1];
arr2[n][1] = arr1[n][0];
arr2[n][0] = tempArr;
}
The second example, in JS the variable shouldn't have brackets next to it, as it's just a loosely typed variable name.
function order(arr){
return [arr[n][1],arr[n][0], arr[n][2], arr[n][3], arr[n][4]];
}
var arr2 = order(arr1);
Next time, before asking you should check the console. The stackoverflow wiki page on JS has lots of great resources for learning to debug JS.
I want to create an array like this:
s1 = [[[2011-12-02, 3],[2011-12-05,3],[5,13.1],[2011-12-07,2]]];
How to create it using a for loop? I have another array that contains the values as
2011-12-02,3,2011-12-05,3,2011-12-07,2
One of possible solutions:
var input = ['2011-12-02',3,'2011-12-05',3,'2011-12-07',2]
//or: var input = '2011-12-02,3,2011-12-05,3,2011-12-07,2'.split(",");
var output = [];
for(i = 0; i < input.length; i += 2) {
output.push([t[i], t[i + 1]])
}
If your values always come in pairs:
var str = '2011-12-02,3,2011-12-05,3,2011-12-07,2',//if you start with a string then you can split it into an array by the commas
arr = str.split(','),
len = arr.length,
out = [];
for (var i = 0; i < len; i+=2) {
out.push([[arr[i]], arr[(i + 1)]]);
}
The out variable is an array in the format you requested.
Here is a jsfiddle: http://jsfiddle.net/Hj6Eh/
var s1 = [];
for (x = 0, y = something.length; x < y; x++) {
var arr = [];
arr[0] = something[x].date;
arr[1] = something[x].otherVal;
s1.push(arr);
}
I've guessed here that the date and the other numerical value are properties of some other object, but that needn't be the case...
I think you want to create an array which holds a set of arrays.
var myArray = [];
for(var i=0; i<100;i++){
myArray.push([2011-12-02, 3]); // The values inside push should be dynamic as per your requirement
}