Iterate through array backwards from index in JavaScript - javascript

I have a bit of Python code that does what I want very nicely, but trying to port that across to JavaScript is proving difficult to do cleanly.
jsonLine = [[0,1],[2,4],[4,8],[9,12],[11,16],[12,13]]
[firstX, firstY] = [9,12]
if [firstX, firstY] in jsonLine:
index = jsonLine.index([firstX, firstY])
lineArray.append(jsonLine[index:])
lineArray.append(jsonLine[index::-1])
jsonLine is an array of coordinates which make up a line, and [firstX, firstY] is the starting point on a line, defined by a user. I'm creating a script that creates two lines, one in either direction from the point the user chooses, which will later be cut shorter based on distance from the user's point.
The desired output in this case will be:
[[[9,12],[11,16],[12,13]],[[9,12],[4,8],[2,4],[0,1]]]
Below is the JavaScript I have, which gets the first of the desired arrays, but using a for loop doesn't feel right, and if I use jsonLine.reverse().slice(featureArray.length-vertex), it seems to duplicate the arrays pushed to lineArray. Is there a cleaner way to slice an array and reverse it?
for (var vertex = 0; vertex < featureArray.length; vertex++){
if (jsonLine[vertex][0] === firstX && jsonLine[vertex][1] === firstY) {
console.log(jsonLine.slice(vertex))
}

You can create a find method to find out the index of the coordinates you're interested in. After that, apply slice and reverse to get the format you're looking for:
var jsonLine = [
[0, 1],
[2, 4],
[4, 8],
[9, 12],
[11, 16],
[12, 13]
],
el = [9, 12],
index, res;
function findElement() {
var i = 0;
for (; i < jsonLine.length; i += 1) {
if (jsonLine[i][0] === el[0] && jsonLine[i][1] === el[1]) {
return i;
}
}
return -1;
}
index = findElement();
res = [
[jsonLine.slice(index)],
[jsonLine.reverse().slice(index - 1)]// -1 because you want to repeat the element.
];
console.log(res);
Fiddle
Note: As #RobG points out in the comments of this answer, if you want to keep the array intact, substitute the second part by jsonLine.slice(0, index + 1).reverse(). Reverse modifies the original array and that might be undesired behaviour (though it wasn't clear in the question whether it was or not).

Related

Javascript tracking the differences between elements in an array?

I have the following simple array:
my_array = [1, 11, 44, 4]
I want to produce a new array consisting of the difference between these elements, so it would be:
diff_array = [10, 33, 40]
What's the best way of going about this?
You could use Array#reduce for iterating and take the absolute delta for pushing to the result array.
Basically you need array.length - 1 deltas and iteration. In this case 3. Reduce takes, if no start value is given, the first two elements and iterates the wanted length. And while it needs the last value for the delta, the last value is returned.
At the end, the returned value of reduce is discarded, becuase it is not used anymore.
1 11 44 4 values
\ / \ / \ /
10 33 40 Math.abs(delta)
var array = [1, 11, 44, 4],
result = [];
array.reduce(function (a, b) {
result.push(Math.abs(a - b));
return b;
});
console.log(result);
here is a simple solution with a plain old for loop
array = [1, 11, 44, 4]
diff = []
for(var i = 1 ; i < array.length ; i++){
diff.push(Math.abs(array[i] - array[i-1]))
}
basically you loop starting at the second element of the array ,, and subtract from from the prev and pushing to the new array .
use this function, pass it the input array, returns the required array.
function diff(array){
var out = []
for (var i = 0; i < array.length-1; i++) {
out.push(Math.abs(array[i+1]-array[i]))
}
return out;
}
Normally one can do this with .reduce() but just for fun lets get some functional.
var myArray = [1, 11, 44, 4],
diff = a => a.length > 1 ? [Math.abs(a[1]-a[0])].concat(diff(a.slice(1))) : [];
console.log(diff(myArray));
Note: The above code is just for demonstration purposes. In your daily JS life you shouldn't do things like this. Use a whatever loop you like but never use recursion in your JS code. You want to see what i mean? Feed this array.
var myArray = Array(1000000).fill().map(_ => ~~(Math.random()*100+1));
It will beautifully crash your browser's tab. Peah..!

Get the highest but also unique number from an array

I have a question. I'm looking for a way to get the higest unique number of an array.
var temp = [1, 8, 8, 8, 4, 2, 7, 7];
Now I want to get the output 4 since that is the unique highest number.
Is there a good & hopefully short way to do that?
Yes, there is:
Math.max(...temp.filter(el => temp.indexOf(el) == temp.lastIndexOf(el)))
Explanation:
First, get the elements which are unique in the array using Array#filter
temp.filter(el => temp.indexOf(el) === temp.lastIndexOf(el)) // [1, 4, 2]
Now, get the max of the numbers from the array using ES6 spread operator
Math.max(...array) // 4
This code is equivalent to
Math.max.apply(Math, array);
If you don't want to get fancy, you can use a sort and loop to check the minimal number of items:
var max = 0;
var reject = 0;
// sort the array in ascending order
temp.sort(function(a,b){return a-b});
for (var i = temp.length - 1; i > 0; i--) {
// find the largest one without a duplicate by iterating backwards
if (temp[i-1] == temp[i] || temp[i] == reject){
reject = temp[i];
console.log(reject+" ");
}
else {
max = temp[i];
break;
}
}
Using the spread operator you can find the hightest number easily
Math.max(...numArray);
The only thing left then is to either filter duplicates from the array beforehand, or remove all the elements that match your maximum number if its a duplicate.
remove beforeHand would be easiest in es6 like this.
Math.max(...numArray.filter(function(value){ return numArray.indexOf(value) === numArray.lastIndexOf(numArray);}));
For a non es6 compatible way to remove duplicates have a look at Remove Duplicates from JavaScript Array, the second answer contains an extensive examinations of several alternatives

Can someone explain why this does not work?

I'm going through the interview cake algorithms. This is basically self-assigned homework. I've given it a few goes, and my solution is fairly ugly, but I don't understand why it's not giving me the correct output. Only one loop executes in the algorithm, and I've tried switching the order, as well as other versions along this line.
I'm a little stuck here, and have two questions relating to this algorithm, which I'm trying to complete in straight-up Javascript.
Here's the problem:
You have an array of integers, and for each index you want to find the product of every integer except the integer at that index. Write a function get_products_of_all_ints_except_at_index() that takes an array of integers and returns an array of the products. Do not use division.
The array [1, 7, 3, 4]
Would return:
[84, 12, 28, 21]
By calculating:
[7*3*4, 1*3*4, 1*7*4, 1*7*3]
My overwrought attempt is below:
var l = [84, 12, 28, 21],
products_before_curr_index = 1,
products_after_curr_index = 1,
backwards_index=1,
forwards_index,
product_array = [];
for(var factor=0; factor<l.length; factor++){
forwards_index=factor+1;
while(forwards_index<l.length){
products_after_curr_index*=l[forwards_index];
forwards_index+=1;
}
if(factor>0){
products_before_curr_index *= l[factor-backwards_index];
backwards_index+=1;
}
product_array.push(products_after_curr_index*products_before_curr_index);
backwards_index=1;
products_after_curr_index = 1;
products_before_curr_index=1;
}
This returns [84, 12, 28, 3]
My questions:
Why doesn't this work? Where am I going wrong?
There must be a more elegant way to do this using slice or map. I'm stumped. Can someone give me a hint here?
This one uses map and reduce methods of Array object.
function get_products_of_all_ints_except_at_index(inList) {
var product = function (x, y) { return x * y; };
var lists = inList.map(function (v, i, a) {
return a.slice(0, i).concat(a.slice(i + 1, a.length));
});
return lists.map(function (v, i, a) { return v.reduce(product); });
}
// test case
console.log(get_products_of_all_ints_except_at_index([1, 7, 3, 4]));
Yeah it looks like you have overcomplicated it a bit. The problem description gives you a bit of a hint on how to solve the problem. For each integer in the array, you want to find the product of all the other integers. In other words, you can loop over each item in the array, then loop over each item in the array again (aka, a nested loop) and add up all the products except for the current index of the first array.
For example:
var a = [1, 7, 3, 4];
var b = [];
a.forEach(function( value_1 ) {
var product = 1;
a.forEach(function( value_2 ) {
if ( value_1 != value_2 )
product *= value_2;
});
b.push( product );
});
console.log( b ); // [84, 12, 28, 21]
Your original solution doesn't work because you only ever go back once. You use a while loop to go forward through the entire array to calculate the product of all the elements after, but you only use one single calculation to go backwards:
products_before_curr_index *= l[factor-backwards_index];
So you're only ever getting the product of the value immediately before the current index. You never go back further. If you're wondering, you only happen to get the third value (28) right because the first number is 1 (aka, multiplying by 1 wouldn't have done anything anyway). Try changing that first number to anything that isn't 1 and you'll see that the third calculation also fails.
I didn't particularly liked the solution given by Interview Cake, I felt it was complicated. I may not have the most optimized solution, and I used Numpy which is not clear if we can (but it doesn't say we can't, so...)
It worked for all test cases and I feel it's way more simple/easy to grasp:
` import numpy as np
def get_products_of_all_ints_except_at_index(int_list):
if len(int_list) < 2:
raise IndexError("you need two numbers at least")
products = []
for i in range(len(int_list)):
temp_list = int_list.copy()
del temp_list[i]
prod = np.prod(temp_list)
products.append(prod)
return products

Getting nth smallest number location in array

Pretty basic question but I can't seem to find any examples of how to solve it in Javascript.
I would like to create a function where you pass a number representing "n" and it returns the location of the nth smallest number in the array.
For instance, if I did:
array = [5,6,1,1,1,8]
n = 3
location = nth_smallest(array, n)
Location would then be equal to 4, because the third lowest number is 1 however I would like to skip the first several duplicates of that number.
The common solution to finding the location of the nth smallest number is by doing:
array = [5,6,1,1,1,8]
n = 3
nth_lowest = array.slice(0).sort()[n]
location = $.inArray(nth_lowest, array)
However the problem is that it will always return the location being 2 because it knows that the third smallest number is 1 but the inArray function doesn't care about duplicates.
Is there any way to do this, possibly without using the sort function? It seems to take up a lot of processing and this is a function that will be run quite often.
// remap array as pairs of value and index
// e.g. change [5, 6, 1] to [[5, 0], [6, 1], [1, 2]]
var augmented_array = array.map(function(val, index) { return [val, index]; });
// sort pairs by the first position, breaking ties by the second
augmented_array.sort(function(a, b) {
var ret = a[0] - b[0];
if (ret == 0) ret = a[1] - b[1];
return ret;
});
// example array will now be [[1, 2], [5, 0], [6, 1]]
// so we get the location by just looking at the second position of a pair
var location = augmented_array[n - 1][1];
If you want the last location having that value, after the sort do:
var position = n - 1;
while (position < augmented_array.length - 1 &&
augmented_array[position][0] == augmented_array[position + 1][0]) {
++position;
}
var location = augmented_array[position][1];
Or if you want the first location, do:
var position = n - 1;
while (position > 0 &&
augmented_array[position][0] == augmented_array[position - 1][0]) {
--position;
}
var location = augmented_array[position][1];
Of course, lastIndexOf or indexOf, as suggested by one of the other answers would result in less code.
If I understand your question correctly, you are looking for the position of the last instance of the n-th lowest number? If so, try this:
array = [5,6,1,1,1,8];
n = 3;
nth_smallest = array.slice(0).sort()[n];
location = array.lastIndexOf(nth_smallest); // assumes non-ancient browser and/or shim
A haxy shim of lastIndexOf could be done like so:
function lastIndexOf(array,item) {
return array.join("\x00").match(new RegExp(".*\x00"+item+"\x00"))[0].split("\x00").length-1;
}
This shim would need calling like so: location = lastIndexOf(array,nth_smallest);
const arr = [9,3,4,5,3,4,6,7,8,];
arr.sort((a,b)=>{return a-b});
console.log(arr[arr.length-1]);
arr.sort((a,b)=>{return a-b});
console.log(arr[0]);
to find lowest number or highest number in array first you need to sort any array then array will be short sequence after the sort any array always in index (arr[0]) will be lowest number in any array and (arr[arr.lenght-1]) always highest number because we sort in sequnece
thanks...

Javascript: is there a data structure, "matrix", thing[x][y]?

I don't know the terminology but I want to get it simpler:
var thingTopic1 =['hello','hallo', ..., 'hej'];
var thingTopic2 =['a','b',...,'c'];
...
var thingTopic999 =['x,'y',...,'?'];
so I want to access the data like thing[para1][para2], is there some ready data structure for it or do I need to create messy function with the things? Please, note that sizes of things differ.
You can have arrays of arrays, and the size of each row can be different.
var matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0]
];
The variable "matrix" will refer to an array with length 4. The syntax you use to refer to (say) the "5" in the second row is exactly what you suggested:
var theFive = matrix[1][1];
You can "build" a matrix like that incrementally of course.
var matrix = [];
for (var i = 1; i < 10; ++i) {
var row = ~~((i - 1) / 3);
if (!matrix[row]) matrix[row] = [];
matrix[row][(i - 1) % 3] = i;
}
matrix.push([0]);
When you set an integer-indexed "property" of an Array instance, Javascript makes sure that the "length" property of the array is updated. It does not allocate space for "holes" in the array, so if you set element number 200 first, there's still just one thing in the array, even though "length" would be 201.
No, there is no data structure for that, but you can easily accomplish it by combining arrays.
You can create an array that contains arrays, which is called a jagged array:
var thing = [
['hello','hallo','goddag','guten tag','nuqneH','hej'],
['a','b','c','d','e','f','g','h','i','j'],
['x,'y','z']
];
Notice how the inner arrays can have different length, which is where the term "jagged" comes from.
You can take advantages from OOP of ES6 :
class Matrix extends Array {
constructor(...rows) {
if(rows.some( r => !Array.isArray(r)))
throw new TypeError('Constructor accepts only rows as array')
super(...rows)
}
push(...rows) {
if(rows.some( r => !Array.isArray(r)))
throw new TypeError('Push method accepts array(s)')
super.push(...rows)
}
}
Use case 1:
Use case 2 :

Categories

Resources