I have a bi-dimensional array made of 0s and 1s.
I need to 'crop' the array so there are no rows / columns that only have 0s in them.
This is how I created the array.
var image = [];
for (y = 0; y < height; y++)
{
image[y] = [];
}
Image example of the array.
And this is what I need the array to be cropped to.
First you should clean the rows by detecting if a an array is full of zeros.
You can use Array.prototype.every.
Example :
This function return is an array is empty or not.
function isEmpty(arr) {
return arr.every(function(item) {
return item===0;
});
}
And you can write an algorithm that detect each rows from 0 until you have a not empty line. And you make the same thing from the end of the array.
After cleaning the rows, you do the do the same thing for cols, and using the same algorithm by using a function that give you each cols as an array.
Here is a complete example that do the job :
var arr = [
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,0,0,0,0],
[0,0,1,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,0,0,1,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0]
];
function cleanRows(arr) {
var i=0;
var j=arr.length-1;
while(i<arr.length && isEmpty(arr[i])) {
i++;
}
while(j>i && isEmpty(arr[j])) {
j--;
}
return arr.slice(i,j+1);
}
function cleanCols(arr) {
var i= 0, j=arr[0].length-1;
while(i<j && isEmpty(getCol(arr,i))) {
i++;
}
while(j>i && isEmpty(getCol(arr,j))) {
j--;
}
j++;
// clear each line
return arr.map(function(row) {
return row.slice(i,j);
})
}
function getCol(arr,colIndex) {
return arr.map(function(item) {
return item[colIndex];
});
}
function isEmpty(arr) {
return arr.every(function(item) {
return item===0;
});
}
var newArr = cleanRows(arr);
newArr = cleanCols(newArr);
console.log(newArr);
Related
I need to convert a nested array into 2D in javascript, somewhat similar to the question answered for python at link
How to convert 2d nested array into 2d array single?
For example, the array
[[[[[[[[
[16,12],[16,13],[16,14]]
],
[[[[[[
[46,42],[46,43]
]]]]],[
[62,58],[62,59],[62,60]
]]]]]],
[103,102]],[[118,114],[118,115],[118,116]]
]
needs to be converted to
[[16,12],[16,13],[16,14],[46,42],[46,43],[62,58],[62,59],[62,60],[103,102],[118,114],[118,115],[118,116]]
Please help, thanks in advance
This is what I tried, finally works after many trials :
function removeNestArray2D(object) {
var result = [];
if (Array.isArray(object)) { // check if object is valid array
for(var i=0; i<object.length; i++) {
if(!Array.isArray(object[i])) { // check is each of array element is a valid array
return object;
}
else {
var tmp = removeNestArray2D(object[i]);
if(tmp.length == 1) {
result = tmp[0];
}
else if (tmp.length == 2 && Number.isInteger(tmp[0]) && Number.isInteger(tmp[1])) {
result.push(tmp);
}
else {
for (var j=0; j<tmp.length; j++) {
result.push(tmp[j]);
}
}
}
}
}
return result;
}
Recursive approach will help here. Check each array item if there are size 2 and both are number values then push to result array otherwise continue iteration recursively.
const arr = [[[[[[[[
[16,12],[16,13],[16,14]]
],
[[[[[[
[46,42],[46,43]
]]]]],[
[62,58],[62,59],[62,60]
]]]]]],
[103,102]],[[118,114],[118,115],[118,116]]
];
const get2dArray = arr => {
const res = [];
const pushRecursive = arr => {
if (arr.length == 2 && arr.every(x => Number.isInteger(x))) {
res.push(arr);
} else {
arr.forEach(pushRecursive);
}
};
pushRecursive(arr);
return res;
};
console.log(get2dArray(arr));
function removeNestArray2D(object) {
var result = [];
if (Array.isArray(object)) { // check if object is valid array
for(var i=0; i<object.length; i++) {
if(!Array.isArray(object[i])) { // check is each of array element is a valid array
return object;
}
else {
var tmp = removeNestArray2D(object[i]);
if(tmp.length == 1) {
result = tmp[0];
}
else if (tmp.length == 2 && Number.isInteger(tmp[0]) && Number.isInteger(tmp[1])) {
result.push(tmp);
}
else {
for (var j=0; j<tmp.length; j++) {
result.push(tmp[j]);
}
}
}
}
}
return result;
}
var sampleArray = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16],
[17,18,19,20]
];
function printSpiral(myArray, clockwise) {
//anti-clockwise:
//1,5,9,13,17, 18,19,20, 16,12,8,4, 3,2, 6,10,14, 15,11,7
if(!clockwise) {
myArray = transpose(myArray)
//console.log(myArray)
}
var rows = myArray.length;
var cols = myArray[0].length;
if(rows <= 1) {
return myArray[0];
}
if(cols === 0) {
return myArray[0];
}
var firstRow = myArray[0];
var newMatrix = [];
var newRow;
var rowIdx;
var colIdx = myArray[1].length - 1;
for(colIdx; colIdx >=0; colIdx--) {
newRow = [];
for(rowIdx = 1; rowIdx < rows; rowIdx++) {
newRow.push(myArray[rowIdx][colIdx])
//console.log(newRow)
}
newMatrix.push(newRow)
}
//console.log(newMatrix)
firstRow.push.apply(firstRow,printSpiral(newMatrix));
//console.log(firstRow)
return firstRow
//return newMatrix
// Spiral Order
// 1,2,3,4, 8,12,16,20, 19,18,17, 13,9,5, 6,7, 11,15, 14, 10
}
var result = printSpiral(sampleArray, false);
console.log(result)
I am trying to print the array spirally but anticlockwise. I have tried to transpose the matrix but it doesn't help how do I print the following array.
//1,5,9,13,17, 18,19,20, 16,12,8,4, 3,2, 6,10,14, 15,11,7
Please help
Its not very elegant, but here's the juiste of the algorithm:
<script>
var array = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16],
[17,18,19,20]];
function spiral(array) {
var list = [];
var array = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
list.push(array[0]);
array.shift()
while (typeof array[0] !== 'undefined'){
var array = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
array.reverse();
list.push(array[0]);
array.shift();
}
return list
}
var list = spiral(array)
document.writeln(list);
</script>
basically the idea is as follows, a rotate 90 degrees counterclockwise is done with a transpose and flip. then we pop the top row, and do it again.
so we transpose the array, array.reverse to flip it, push our row into a list, array.shift to pop the row, repeat.
Also the main benefit of this method is that it wont care what the dimensions of your array are. they can be asymmetric or not.
Given an array I want to find the largest sub array by the length i.e
var table = [
["Protein",["Grilled Chicken","Lamb"]],
["Fats",["rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"]],
["Vegatables",["Carrots","Eggs","Milks","Peppers"]]
];
I want it to return ["Carrots","Eggs","Milks","Peppers"]
Heres my code
function findBiggestSubArray(array){
var biggestArrayIndex = 0;
for(var i=0;i<array.length;i++){
if(i === (array.length-1)){
//We have reached the end of the array then return the array
console.log("Reached the End");
return array[biggestArrayIndex];
} else {
if(!array[biggestArrayIndex][1].length >= array[i][1].length){
biggestArrayIndex = i;
}//End of Inner else block
}//End of Outer else block
}//End of forloop
}
General solution, to find the most largest array in an array-structure:
I would do it with recursion, so the most biggest Array will be found, in any depth..
/**
* array -> The array to check,
* biggestArray -> The most biggestArray found so far
*/
function findBiggestArray(array, biggestArray){
biggestArray = biggestArray || [];
if (array.length > biggestArray.length)
biggestArray = array;
for (var i = 0; i < array.length; i++) {
if (array[i] instanceof Array)
biggestArray = findBiggestArray(array[i],biggestArray)
}
return biggestArray;
}
var multiArray = [
["1", "2", ["234", "334"]],
[1,2,3,4,5, [1,2,3,4,5,6,7,7]]
]
var biggest = findBiggestArray(multiArray)
console.log(biggest)
// This also works!
console.log(findBiggestArray([1, [1,2,3]]))
Oneliner for this special case
// Sort the array by the length of the subarray at position 1, and return the first item
var category = table.sort(function(a, b) { return b[1].length - a[1].length })[0]
// ES6-Syntax
var category = table.sort((a, b) => b[1].length - a[1].length)[0]
category // => ["CategoryName", [ITEMS..]]
I would do this way (see the comments in the code for explanation):
var table = [
["Protein", ["Grilled Chicken", "Lamb"]],
["Fats", ["rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"]],
["Vegatables", ["Carrots", "Eggs", "Milks", "Peppers"]]
];
function findBiggestSubArray (array) {
// Initialise empty array.
var bigSubArray = ["", []];
// Loop through the given array.
for (var i = 0; i < array.length; i++) {
// Check if the current biggest one is bigger than the saved array.
if (array[i][1].length > bigSubArray[1].length) {
// If bigger, replace it with current array.
bigSubArray = array[i];
}
}
// Return the biggest sub array.
return bigSubArray[1];
}
console.log(findBiggestSubArray(table));
This question already has answers here:
Remove items from array with splice in for loop [duplicate]
(5 answers)
Closed 6 years ago.
i have created an array for vowels position in string now i want reomve all elements that have value -1 from this array but its not working
function translatePigLatin(str) {
var vowelp=[];
var newarr=str.split('');
vowelp.push(newarr.indexOf('a'));
vowelp.push(newarr.indexOf('e'));
vowelp.push(newarr.indexOf('i'));
vowelp.push(newarr.indexOf('o'));
vowelp.push(newarr.indexOf('u'));
var minvowel=vowelp[0];
for(var i=0;i<vowelp.length;i++) { //looping through vowel's position array
if(vowelp[i]==-1) {
vowelp.splice(i,1);
console.log(vowelp[i]);
}
}
return vowelp;
}
input-translatePigLatin("consonant");
output that i am getting is[6,-1,1] but i want [6,1]
Simple way is to use filter()
function translatePigLatin(str) {
var vowelp = [];
var newarr = str.split('');
vowelp.push(newarr.indexOf('a'));
vowelp.push(newarr.indexOf('e'));
vowelp.push(newarr.indexOf('i'));
vowelp.push(newarr.indexOf('o'));
vowelp.push(newarr.indexOf('u'));
var minvowel = vowelp[0];
return vowelp.filter(function(v) {
return v != -1;
})
}
console.log(translatePigLatin("consonant"));
In your case you need to decrement the value of i in case of item removal otherwise it will skip the next element.
function translatePigLatin(str) {
var vowelp = [];
var newarr = str.split('');
vowelp.push(newarr.indexOf('a'));
vowelp.push(newarr.indexOf('e'));
vowelp.push(newarr.indexOf('i'));
vowelp.push(newarr.indexOf('o'));
vowelp.push(newarr.indexOf('u'));
var minvowel = vowelp[0];
for (var i = 0; i < vowelp.length; i++) { //looping through vowel's position array
if (vowelp[i] == -1) {
vowelp.splice(i, 1);
i--;
console.log(vowelp[i]);
}
}
return vowelp;
}
console.log(translatePigLatin("consonant"));
You can make it more simple using map() and filter() with an array
function translatePigLatin(str) {
return ['a', 'e', 'i', 'o', 'u'].map(function(v) {
return str.indexOf(v);
}).filter(function(v) {
return v != -1;
});
}
console.log(translatePigLatin("consonant"));
you are calling splice on the same array you are iterating over. Rememeber splice is mutable and it deletes from the original array. As a result of that your index tracking logic is getting messed up. So instead you could use delete[i] (which does not mess up the indexes and creates a void)
function translatePigLatin(str) {
var vowelp=[];
var newarr=str.split('');
vowelp.push(newarr.indexOf('a'));
vowelp.push(newarr.indexOf('e'));
vowelp.push(newarr.indexOf('i'));
vowelp.push(newarr.indexOf('o'));
vowelp.push(newarr.indexOf('u'));
var minvowel=vowelp[0];
for(var i=0;i<vowelp.length;i++) { //looping through vowel's position array
if(vowelp[i]==-1) {
delete vowelp[i];
}
}
return vowelp;
}
console.log(translatePigLatin("consonant")); //prints [6, 3: 1]
which means you have 6 at index 0 and 1 at index 3
I would prefer a simpler code:
function translatePigLatin(str) {
var vowelp = [];
var vowels = ['a','e','i','o','u'];
for (var i = 0; i < vowels.length; i++) {
var index = str.indexOf(vowels[i]);
if (index != -1) {
vowelp.push(index);
}
}
return vowelp;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Easiest way to find duplicate values in a JavaScript array
Javascript array sort and unique
I have the following array
var output = new array(7);
output[0]="Rose";
output[1]="India";
output[2]="Technologies";
output[3]="Rose";
output[4]="Ltd";
output[5]="India";
output[6]="Rose";
how can i remove the duplicate elements in above array.Is there any methods to do it?
You can write a function like this
function eliminateDuplicates(arr) {
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i<len;i++) {
obj[arr[i]]=0;
}
for (i in obj) {
out.push(i);
}
return out;
}`
Check this here
Maybe more complex than you need but:
function array_unique (inputArr) {
// Removes duplicate values from array
var key = '',
tmp_arr2 = {},
val = '';
var __array_search = function (needle, haystack) {
var fkey = '';
for (fkey in haystack) {
if (haystack.hasOwnProperty(fkey)) {
if ((haystack[fkey] + '') === (needle + '')) {
return fkey;
}
}
}
return false;
};
for (key in inputArr) {
if (inputArr.hasOwnProperty(key)) {
val = inputArr[key];
if (false === __array_search(val, tmp_arr2)) {
tmp_arr2[key] = val;
}
}
}
return tmp_arr2;
}
Code taken from: http://phpjs.org/functions/array_unique:346
You can remove dups from an array by using a temporary hash table (using a javascript object) to keep track of which images you've already seen in the array. This works for array values that can be uniquely represented as a string (strings or numbers mostly), but not for objects.
function removeDups(array) {
var index = {};
// traverse array from end to start
// so removing the current item from the array
// doesn't mess up the traversal
for (var i = array.length - 1; i >= 0; i--) {
if (array[i] in index) {
// remove this item
array.splice(i, 1);
} else {
// add this value to index
index[array[i]] = true;
}
}
}
Here's a working example: http://jsfiddle.net/jfriend00/sVT7g/
For sizable arrays, using an object as a temporary index will be many times faster than a linear search of the array.
First of all, you'll want to use the array literal (var output = []) to declare your array. Second, you'll want to loop through your array and store all the values in a second array. If any value in the first array matches a value in the second array, delete it and continue looping.
Your code would look like this:
var output = [
"Rose",
"India",
"Technologies",
"Rose",
"Ltd",
"India",
"Rose"
]
var doubledOutput = [];
for(var i = 0; i < output.length; i++) {
var valueIsInArray = false;
for(var j = 0; j < doubledOutput.length; j++) {
if(doubledOutput[j] == output[i]) {
valueIsInArray = true;
}
}
if(valueIsInArray) {
output.splice(i--, 1);
} else {
doubledOutput.push(output[i]);
}
}
Please note, the above code is untested and may contain errors.