Javascript get object sequence out of array - javascript

I have different kind of javascript objects, they all have a property 'row'.
var row1 = {
row: 1
};
var row2 = {
row: 2
};
var row3 = {
row: 3
};
var row4 = {
row: 4
};
...
I have an array defined as follow:
var objArray = [];
In this array it's possible to have multiple 'rows'. The sequence is always te same starting from the lower row to a higher row.
Now I want to get the objects that are linked next to each other (like 4 in a row). In my case it's also possible to have 3 in a row, 5 in a row and so on..
Example:
objArray.push(row0);
objArray.push(row1);
objArray.push(row2);
objArray.push(row3);
objArray.push(row5);
objArray.push(row6);
objArray.push(row7);
objArray.push(row9);
objArray.push(row10);
objArray.push(row12);
In this case I need 2 lists, 1 containing row0 to 3 and one containing 5 to 7.
I've tried a bit in this JSFiddle: Here we can see the console output
If you need more clarification, please ask.
Thanks in advance!

I made a fiddle that does just this for you:
for(var i = 0; i < objArray.length; i++) {
if(currentnum !== -1)
{
var result = objArray[i].row - currentnum;
currentnum = objArray[i].row;
if(result === 1)
{
currentarray.push(objArray[i]);
} else {
arrayofarrays.push(currentarray);
currentarray = [];
currentarray.push(objArray[i]);
}
} else {
currentnum = objArray[i].row;
currentarray.push(objArray[i]);
}
}
arrayofarrays.push(currentarray);
http://jsfiddle.net/B76a8/6/

Since you have already figured how to keep the counter and reset it for each new group you can do
var counter = 1,
lastIndex = 0;
//see chrome dev tools, I need to return objects beginning at the 3rd place untill the 7th place in the array
//how do I get these objects?
for (var i = 0; i < objArray.length; i++) {
if ((i < objArray.length - 1 && objArray[i].row + 1 == objArray[i + 1].row) ||
(i == objArray.length - 1 && objArray[i - 1].row == objArray[i].row - 1)) {
counter++;
} else {
// here we output the grouped items
console.log(objArray.slice(lastIndex, counter+lastIndex));
lastIndex = counter+lastIndex;
counter = 1;
}
}
Demo at http://jsfiddle.net/B76a8/7/
output
[Object { row=0}, Object { row=1}]
[Object { row=3}, Object { row=4}, Object { row=5}, Object { row=6}, Object { row=7}, Object { row=8}]
[Object { row=10}]

First, let's sort the array:
objArray.sort(function(a,b){ return a.row - b.row });
Then, for the given n, this should return you next and previous elements:
function getElement(array, n)
{
var ret = [];
for (var i=0; i<array.length; i++)
if (array[i].row == n)
{
if (i > 0) ret.push(array[i-1]);
if (i < array.length-1) ret.push(array[i+1]);
}
return ret;
}
As getting all the other options with the same color is a different thing let's do it through:
function getByColor(array, color)
{
var ret = [];
for (var i=0; i<array.length; i++)
if (array[i].color == color)
ret.push(array[i]);
return ret;
}
Then you can merge both of the arrays by using concat

Related

Push duplicate items into a separate array in Javascript with for loop?

For some reason, the manipulated doubleArray below is not shown in the console. Any variables that I declare after the for loop won't show to the console on both cases. Consider that in the first algorithm, there is only one for loop with x being incremented everytime. Whereas, in the second algorithm, it's a nested for loop. Can someone help me fix my error in both algorithms?
First Algorithm:
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3];
var doubleValue = [];
var x = 0;
for (i = 0; i < helloWorld.length; i++) {
x = x + 1;
if (helloWorld[i] === helloWorld[x] && i !== x) {
doubleValue.push(helloWorld[i])
console.log(helloWorld[i]);
} else {
continue;
}
}
console.log(doubleValue);
};
The second Algorithm:
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3];
var doubleValue = [];
for (i = 0; i < helloWorld.length; i++) {
for (x = 1; x < helloWorld.length; i++) {
if (helloWorld[i] === helloWorld[x] && i !== x) {
doubleValue.push(helloWorld[x]);
}
}
}
console.log(doubleValue);
};
In first algorithm, you are only checking if the number at current index is equal to the number at the next index, meaning you are only comparing numbers at consecutive indexes. First algorithm will work only if you have duplicate numbers on consecutive indexes.
In second algorithm, you are incrementing i in both loops, increment x in nested loop, change x = 1 to x = i + 1 and your error will be fixed.
Here's the fixed second code snippet
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3, 1, 2];
var doubleValue = [];
for (let i = 0; i < helloWorld.length; i++) {
for (let x = i + 1; x < helloWorld.length; x++) {
if (helloWorld[i] === helloWorld[x] && i !== x) {
doubleValue.push(helloWorld[x]);
}
}
}
console.log(doubleValue);
};
isDuplicate();
Heres's another way to find the duplicates in an array, using an object. Loop over the array, if current number is present as key in the object, push the current number in the doubleValue array otherwise add the current number as key-value pair in the object.
const isDuplicate = function() {
const helloWorld = [1,2,3,4,3, 1, 2];
const doubleValue = [];
const obj = {};
helloWorld.forEach(n => obj[n] ? doubleValue.push(n): obj[n] = n);
console.log(doubleValue);
};
isDuplicate();
Not entirely sure what you are trying to do. If you are only looking for a method to remove duplicates you can do the following:
const hello_world = [1, 2, 2, 3, 4, 5, 5];
const duplicates_removed = Array.from(new Set(hello_world));
A set is a data object that only allows you to store unique values so, when converting an array to a set it will automatically remove all duplicate values. In the example above we are creating a set from hello_world and converting it back to an array.
If you are looking for a function that can identify all the duplicates in an array you can try the following:
const hello_world = [1, 2, 2, 3, 4, 5, 5];
const duplicates_found = hello_world.filter((item, index) => hello_world.indexOf(item) != index);
The main problem by finding duplicates is to have nested loop to compare each element of the array with any other element exept the element at the same position.
By using the second algorithm, you can iterate from the known position to reduce the iteration count.
var isDuplicate = function(array) {
var doubleValue = [];
outer: for (var i = 0; i < array.length - 1; i++) { // add label,
// declare variable i
// no need to check last element
for (var j = i + 1; j < array.length; j++) { // start from i + 1,
// increment j
if (array[i] === array[j]) { // compare values, not indices
doubleValue.push(array[i]);
continue outer; // prevent looping
}
}
}
return doubleValue;
};
console.log(isDuplicate([1, 2, 3, 4, 3])); // [3]
You could take an object for storing seen values and use a single loop for getting duplicate values.
const
getDuplicates = array => {
const
seen = {}
duplicates = [];
for (let value of array) {
if (seen[value]) duplicates.push(value);
else seen[value] = true;
}
return duplicates;
};
console.log(getDuplicates([1, 2, 3, 4, 3])); // [3]
Your first algorithm doesn't work because it only looks for duplicates next to each other. You can fix it by first sorting the array, then finding the duplicates. You can also remove the x and replace it by ++i in the loop.
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3,6];
var doubleValue = [];
helloWorld = helloWorld.sort((a, b) => { return a - b });
for (i = 0; i < helloWorld.length; i++) {
if (helloWorld[i] === helloWorld[++i]) {
doubleValue.push(helloWorld[i])
console.log(helloWorld[i]);
} else {
continue;
}
}
console.log(doubleValue);
};
isDuplicate();
For the second algorithm loop, you probably meant x++ instead of i++ in the second loop. This would fix the problem.
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3,4];
var doubleValue = [];
for (i = 0; i < helloWorld.length; i++) {
for (x = i + 1; x < helloWorld.length; x++) {
if (helloWorld[i] === helloWorld[x]) {
doubleValue.push(helloWorld[x]);
}
}
}
console.log(doubleValue);
};
isDuplicate()
The first algorithm can't be fixed, it can only detect consecutive duplicates,
in the second algorithm you increment i in both loops.
To avoid the duplicates beeing listed too often, you should start the second loop with i + 1

Pushing elements inside an array in a loop, when I dont push one element, all the rest appear as "undefined"

I have a for loop and an array and I want to push a new element in to the array when it meets a certain condition, in this case i!=5, when the program doesn't push an element in the array, because of that condition, the remaining elements tu push appear as undefined.
function myFunction() {
var array = [];
var sh_test = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('test');
var dataRange;
for (var i = 0; i < 20; i++) {
if (i != 5)
array.push(i);
dataRange = sh_test.getRange(i + 1, 10);
dataRange.setValue(array[i]);
}
}
I expect the output
1
2
3
4
6
7
8
and so on...
But I get
1
2
3
4
undefined
undefined
undefined
undefined
undefined
and so on...
What is it that I am not seeing? How can I fix this?
You do dataRange.setValue(array[i]); however after the first i!=5 array doesnt have that many elements for array[i] to be defined. In short the value of i increases with each iteration of the loop, but the number of elements does not. You could perhaps just use array length to access the last element.
for (var i=0;i<20;i++)
{
if (i!=5)
array.push(i);
dataRange = sh_test.getRange(i+1,10);
dataRange.setValue(array[array.length-1]);
}
When i is in the range 0 to 4, array.push(i) assigns i to array[i]. But after you skip i == 5, the array indexes are off by 1. When i == 6, array.push(i) assigns it to array[5], and there's nothing yet in array[6]. This goes on for the rest of the loop: the push() function assigns to array[i-1], but you use dataRange.setValue(array[i]), and array[i] hasn't been set yet. So you get undefined all those times.
It's not clear what you're really trying to do here, but you can simply do
dataRange.setValue(i);
to get the current index of the loop.
In your function:
for (var i = 0; i < 20; i++) {
if (i != 5)
array.push(i);
dataRange = sh_test.getRange(i + 1, 10);
dataRange.setValue(array[i]);
}
is the same as:
for (var i = 0; i < 20; i++) {
if (i != 5){
array.push(i); // <-- array doesn't grow when i == 5
}
dataRange = sh_test.getRange(i + 1, 10);
dataRange.setValue(array[i]); // <-- array[i] is increasing even when the array doesn't grow
}
You could only set the values in the case were i != 5
function myFunction() {
var array = [];
var sh_test = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('test');
var dataRange;
for (var i = 0; i < 20; i++) {
if (i != 5) {
array.push(i);
dataRange = sh_test.getRange(i + 1, 10);
dataRange.setValue(array[array.length - 1]);
}
}
}
Gives:
0
1
2
3
4
6
7
...
19
(Total of 20 lines with a blank line where 5 would be)
OR, if you want the last item displayed TWICE:
function myFunction() {
var array = [];
var sh_test = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('test');
var dataRange;
for (var i = 0; i < 20; i++) {
if (i != 5)
array.push(i);
dataRange = sh_test.getRange(i + 1, 10);
dataRange.setValue(array[array.length - 1]);
}
}
Gives:
0
1
2
3
4
4
6
7
...
19
(Total of 20 lines)
Try this:
function myFunction() {
var array=[];
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
sh.clear();
var rg=sh.getRange(1,10,20,1);
var vA=rg.getValues();
for (var i=0;i<vA.length;i++) {
if(i!=5) {
array.push(i);
vA[i][0]=array.join(',');
}
}
rg.setValues(vA);
}

Print two elements from array with for loop

I'm new in JavaScript and i am trying to print only two elements from array with FOR LOOP and brake & continue statements
for example i want to be printed 3 and 8
I tried this:
var array= [1,2,3,4,5,6,7,8];
for (var i = 0; i < array.length; i++) {
if (i == 3) {
alert(i);
continue;
}
if ( i == 8) {
alert(i);
}
}
All arrays start at the first position of 0 and go up from there. So in your code you are thinking you are comparing 3 == 3 in but really you are comparing 2 == 3. If you compare the array position value instead of the loop value your problem is fixed.
var array = [1, 2, 3, 4, 5, 6, 7, 8];
for (var i = 0; i < array.length; i++) {
if (array[i] == 3) {
alert(array[i]);
}
else if (array[i] == 8) {
alert(array[i]);
}
}
Try this one if you need to check for values in array and not index. Imo, values in array need not be similar as index values,they can be anything.
var array= [1,2,3,4,5,6,7,8];
for(var i = 0; i < array.length; i++)
{
if (array[i]== 3 || array[i] == 8)
{
alert(array[i]);
}
}
What about using a filter?
const array = [1,2,3,4,5,6,7,8];
const matches = array.filter(a => a === 3 || a === 8);
console.log(matches[0], matches[1]);
// The filter uses the lambda function. It's the same thing as the following:
const matches = array.filter(function(a) {
return a === 3 || a === 8;
});

How to programmatically create 3D array that increments to a defined number, resets to zero, and increments again?

Starting with this initial 2D array:
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
I need to create this 3D array programmatically:
var fullArray = [
[[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]],
[[3,4],[0,1],[5,6],[2,3],[6,7],[3,4]],
[[4,5],[1,2],[6,7],[3,4],[0,1],[4,5]],
[[5,6],[2,3],[0,1],[4,5],[1,2],[5,6]],
[[6,7],[3,4],[1,2],[5,6],[2,3],[6,7]],
[[0,1],[4,5],[2,3],[6,7],[3,4],[0,1]],
[[1,2],[5,6],[3,4],[0,1],[4,5],[1,2]],
[[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]],
[[3,4],[0,1],[5,6],[2,3],[6,7],[3,4]],
[[4,5],[1,2],[6,7],[3,4],[0,1],[4,5]],
[[5,6],[2,3],[0,1],[4,5],[1,2],[5,6]]
];
See the pattern?
On each pair, the [0] position should increment to 6 (from any starting number <= 6) and then reset to 0 and then continue incrementing. Similarly, the [1] position should increment to 7 (from any starting number <= 7) and then reset to 1 and then continue incrementing.
In this example, there are 10 2D arrays contained in the fullArray. However, I need this number to be a variable. Something like this:
var numberOf2DArraysInFullArray = 12;
Furthermore, the initial array should be flexible so that initialArray values can be rearranged like this (but with the same iteration follow-through rules stated above):
var initialArray = [[6,7],[2,3],[5,6],[4,5],[1,2],[6,7]];
Any thoughts on how to programmatically create this structure?
Stumped on how to gracefully pull this off.
Feedback greatly appreciated!
Here's a solution, I've separated the methods, and I made it so if instead of pairs it's an N size array and you want the [2] to increase up to 8 and reset to 2, if that's not needed you can simplify the of the loop for(var j = 0; j < innerArray.length; j++)
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
var create3DArray = function(array, size){
var newArray = [initialArray];
for(var i = 0; i < size; i++)
{
newArray.push(getNextArrayRow(newArray[i]));
}
return newArray;
}
var getNextArrayRow = function(array){
var nextRow = [];
for(var i = 0; i < array.length; i++)
{
var innerArray = array[i];
var nextElement = [];
for(var j = 0; j < innerArray.length; j++)
{
var value = (innerArray[j] + 1) % (7 + j);
value = value === 0 ? j : value;
nextElement.push(value);
}
nextRow.push(nextElement);
}
return nextRow;
}
console.log(create3DArray(initialArray,3));
Note, the results from running the snippet are a bit difficult to read...
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
var numOfArrays = 10;
// get a range array [0, 1, 2, ...]
var range = [];
for (var i = 0; i < numOfArrays; i++) {
range.push(i);
}
var result = range.reduce(function(prev, index) {
if (index == 0) {
return prev;
}
prev.push(transformArray(prev[index - 1]));
return prev;
}, [initialArray])
console.log(result);
function transformArray(arr) {
return arr.map(transformSubArray)
}
function transformSubArray(arr) {
return arr.map(function(val) {
return val == 7 ? 0 : val + 1;
})
}
Here's a pretty simple functional-ish implementation

selection sort does not work in javascript

I am trying to use a selection sort for javascript but it does not seem to work, can somebody help me please?
I create a function to sort an array,
then I get the value from the text box, and store it in an array named inputString
then I split the array by comma, and store it in an array named inputNumbers
If in my text box exist non number, an error will be displayed otherwise display the sorted value.
function sortNow(form) {
var nanExists = false;
var inputString = document.getElementById("numberID").value;
var inputNumbers = inputString.split(",");
for (var a = 0; a < inputNumbers.length; a++) {
inputNumbers[a] = parseInt(inputNumbers[a], 10);
if (isNaN(inputNumbers[a])) {
nanExists = true;
break;
}
}
inputNumbers = selectionSort(inputNumbers); //sort the array inputNumbers
if (nanExists)
form.answers.value = "Invalid Input";
else
{
for(var b=0; b < inputNumbers.length; b++)
{
form.answers.value += inputNumbers[b];
}
}
}
/* function to sort an array */
function selectionSort(inputArray) {
for(var i=0; i<inputArray.length; i++)
{
var currentMin = inputArray[i];
var currentMinIndex = i;
for(var j=i+1; j<inputArray.length; j++)
{
if(currentMin > inputArray[j])
{
currentMin = inputArray[j];
currentMinIndex = j;
}
if(currentMinIndex != i)
{
inputArray[currentMinIndex] = inputArray[i];
inputArray[i] = currentMin;
}
}
}
return inputArray;
}
In your code please move the following code segment from inner loop (j) to outer loop (i).
if(currentMinIndex != i)
{
inputArray[currentMinIndex] = inputArray[i];
inputArray[i] = currentMin;
}
See the demo
Please sort the inputArray like this:
inputArray.sort(function(a,b) {
return (a > b) ? 1 : ((a == b) ? 0 : -1);
});
You need to supply a custom sort function to Array.sort because Array.sort() sorts array lexicographically (in dictionary order) according to the string conversion of each element.
See a working demo here
Read up the MDN:Array.sort

Categories

Resources