If I have an array which is 'dynamic', e.g:
var xArray = [2,4,5,5,6,7,8,9,9,8,7,7,6,6,6]
I need to find the closest number (in terms of INDEX) to the last entry, which is not equal to the last entry (in terms of NUMBER)
Kind of hard to explain! So in the case of the array above, the last entry is 6. I'm looking for the closest entry which is different to 6 (could be higher or lower value). in this case it would be
xArray[11] //7
so at the moment I have:
var lastX = xArray[xArray.length -1],
prevX = ?????
Something like :
function diff(arr) {
var a = arr.slice(), last = a.pop(), nxt = a.pop();
while (last == nxt && a.length) nxt = a.pop();
return nxt;
}
FIDDLE
call it like
var diff = diff(xArray);
Try
var xArray = [2, 4, 5, 5, 6, 7, 8, 9, 9, 8, 7, 7, 6, 6, 6]
var index = xArray.length - 1,
num = xArray[index];
while (--index >= 0 && xArray[index] == num);
console.log(index)
//here num will be 11
Demo: Fiddle
Try this,
var xArray = [2,4,5,5,6,7,8,9,9,8,7,7,6,6,6];
var xChangeDetector = null;
for(var I=xArray.length-1; I>=0 ; I--)
{
if(xChangeDetector == null)
{
xChangeDetector = xArray[I];
}
else if(xChangeDetector != xArray[I])
{
xChangeDetector = xArray[I];
break;
}
}
alert(xChangeDetector);
DEMO
function firstDifferent(arr) {
for (var i=arr.length-2; i>=0; i--) {
if (arr[i] != arr[arr.length - 1])
return i;
}
}
var xArray = [2,4,5,5,6,7,8,9,9,8,7,7,6,6,6];
var different = firstDifferent(xArray);
A functional solution could be this one:
var array = [2,4,5,5,6,7,8,9,9,8,7,7,6,6,6]
var lastIndex = array.reduce(function(acc,item,index,arr){
return item !== arr[acc] ? index : acc
}, 0) -1;
console.log(lastIndex);
It is not as efficient as the others because it needs to iterate through the entire array.
Related
Could someone tell me how to get alternate values from a range of values, through Angular js?
monthDataCreation(){
var startDay =1;
var endDay = 10;
for (var a = startDay; a < endDay; a++) {
var element = a;
console.log("list values like 1,2,5,7,9... ")
}
}
what I need is if I set a start value and end value and on loop it I should get alternate values.
If it start with even num 2 ends at 10 then the string of alternate value should be 2,4,6,8,10.
If it start with odd num 1 ends at 10 then the string of alternate value should be 1,3,5,7,9
Is there any angular way of solution
I think you could simply change a++ to a+=2 to achieve the desired output. You then have to change a < endDay to a <= endDay though.
You can use the filter method of Array
var original = [1, 2, 3, 4, 5, 6, 7, 8];
var alternate = original.filter(function(val,idx) {
if(idx%2==0)
return val;
})
console.log(alternate)
function monthDataCreation(start, end) {
var values = []
for (var i = start; i <= end; i += 2) {
values.push(i)
}
return values.join(', ')
}
monthDataCreation(1, 10) will return "1, 3, 5, 7, 9"
monthDataCreation(2, 10) will return "2, 4, 6, 8, 10"
const a = [1, 2, 3, 4, 5, 6]
for (let i = 0; i < a.length; i++) {
if (i % 2 == 0) {
console.log(a[i])
}
}
Array length is 7
Original array
var arr = [2, 4, 6];
Needed array
arr = [null,null,2,null,4,null,6];
0 is not present in array so need to replace with null,
1 is not available replace with null and
2 is available so put 2 in new array so on..
You can use the splice() method on the array
var arr=[2,4,6];
var l = arr[arr.length-1];
for(var i=0; i<=l; i++){
if(arr[i] !== i){
arr.splice(i, 0, null);
}
}
Output : [null, null, 2, null, 4, null, 6]
This modifies the original array.
I will write a permanence case for all answers soon.
function createArrayFromArray(array, length) {
var new_array = new Array(length);
for (var i = 0; i < new_array.length; i++) {
new_array[i] = null;
}
for (var i = 0; i < array.length; i++) {
new_array[array[i]] = array[i];
}
return new_array;
}
console.log(createArrayFromArray(arr, 7)); //[null, null, 2, null, 4, null, 6]
You just need to find the max value in the array and then iterate from 0 to that max, checking each value to see if it was present in the source or not:
var arr = [2, 4, 6];
var max = Math.max.apply(Math, arr);
var result = [];
for (var i = 0; i <= max; i++) {
if (arr.indexOf(i) !== -1) {
result[i] = i;
} else {
result[i] = null;
}
}
Working demo: http://jsfiddle.net/jfriend00/c7p8mkqy/
As I asked in my comments, I'd like to know what problem you're actually trying to solve because it seems like both the original and the newly created data structures are inefficient structures that could probably use different form of data and work more efficiently. But, we can only help you make a wiser choice if you explain the actual problem, rather just your attempted solution.
Given you have the only input arr which you want to fill null inside. Try this:
var arr = [2, 4, 6];
var output = [];
while (arr.length>0){
var first = arr.splice(0,1);
while (output.length<first[0])
output.push(null);
output.push(first[0]);
}
// output should be [null,null,2,null,4,null,6];
Try:
var arr = [2, 4, 6];
var new_arr = [];
var i = 0;
while(i < 7){
var pos = arr.indexOf(i++);
new_arr.push(pos !== -1 ? arr[pos] : null)
}
document.write(JSON.stringify(new_arr, null, 4))
var arr = [2, 4, 6];
var result = new Array(7);
arr.forEach(function(a) { result[a] = a;});
Interesting quiz:
var arr = [2, 4, 6]
var n = 0
while(arr.length > n) {
if(arr[n] !== n) {
arr = arr.slice(0,n).concat(null, arr.slice(n))
}
n++
}
console.log(arr) // [null, null, 2, null, 4, null, 6]
This approach applies to array consists of random number of sorted integers.
var arr = [2, 4, 6];
var narr = (new Array(arr.sort()[arr.length-1]))
arr.map(function(v){
narr[v] = v;
});
for (var i = 0; i<narr.length; i++) narr[i]||(narr[i]=null);
console.log(narr);
Try splice():
var arr = [2, 4, 6];
var i = 0,
l = arr[arr.length - 1];
while (i < l) {
if(i !== arr[i])
arr.splice(i, 0, null);
i++;
}
console.log(arr); //[ null, null, 2, null, 4, null, 6 ]
I have an array of elements.
0,1,2,3,4,5,6,7,8,9
user can pick any number of elements and ask to move them after any 1 particular element.
example: ask for 4,5,7 to be moved after 1 for example, thus resulting in
0,1,4,5,7,2,3,6,8,9
or ask for 0,5 to be moved after 9
1,2,3,4,6,7,8,9,0,5
any pseudo code is greatly appreciated.
move_after= function(after, move_array) {
//remove elements from the array
move_array.forEach(function(element) {
var index = operations.indexOf(element);
operations.splice(index, 1);
});
var after_index = operations.indexOf(after) + 1;
//insert each move_array element to array
move_array.forEach(function(element) {
operations.splice(after_index++, 0, element);
});
}
move_after(2, [0,1]);
doesn't exactly give me what i want
Here a prototype is used, which inserts an array into an array after a specific digit:
Array.prototype.insertIntoArr = function(insert, digit) {
var i = this.indexOf(digit) + 1;
return this.slice(0, i).concat(insert).concat(this.slice(i));
}
The function moveAfter( ... ) first cleans the array from the values of toMove. Second toMove is inserted after the specific digit:
function moveAfter(arr, toMove, after) {
toMove.forEach(function (value) {
arr.splice(arr.indexOf(value), 1);
});
var res = arr.insertIntoArr(toMove, after);
return res;
}
Example
What about something like this: http://plnkr.co/edit/k2h6BWTUCFj5BS4oFF8C
(function(){
var arr = [0,1,2,3,4,5,6,7,8,9];
var userArr = [4,5,7];
var temp = [];
var pos = 1;
for(var i = arr.length; i >= 0; i--){
if(userArr.indexOf(arr[i]) !== -1){
temp.push(arr[i]);
arr.splice(i, 1);
}
}
for(var i = 0; i < temp.length; i++){
arr.splice(arr.indexOf(pos) + 1, 0, temp[i]);
}
console.log(arr);
//outputs [0, 1, 4, 5, 7, 2, 3, 6, 8, 9]
})();
Using your idea
function move_after(orig_array, after, move_array) {
//remove elements from the array
move_array.forEach(function(element) {
var index = operations.indexOf(element);
orig_array.splice(index, 1);
});
var after_index = orig_array.indexOf(after) + 1;
//insert each move_array element to array
move_array.forEach(function(element) {
orig_array.splice(after_index++, 0, element);
});
return orig_array;
}
Then you use
var result = move_after([0, 1, 2] , 2, [0,1]);
Hope it works,
Dan
Try this:
move_after = function (after, move_array) {
var i, s;
s = [];
for (i = 0; i < 10; i++)
{
// only append "i" it if is NOT in move_array
if (move_array.indexOf(i) === -1) s.push(i);
if (i == after) s.push(move_array);
}
return s;
};
Something like this?
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var b = move_after(1, [4, 5, 7]);
var c = move_after(9, [0, 5]);
console.log(a);
console.log(b);
console.log(c);
function move_after(moveAfter, toMove) {
var arr = a.reduce(function (c, e, i) {
if (toMove.indexOf(e) === -1) {
c.push(e);
}
return c;
}, []);
var toMoveAfterIndex = arr.indexOf(moveAfter) + 1;
Array.prototype.splice.apply(
arr, [toMoveAfterIndex, 0].concat(toMove)
);
return arr;
}
If i've got an array like the following as an example:
myArray = [1,4,5,1,5];
How would I remove all the duplicate values (all the 1's and 5's in this example) and only return the unique elements (4 in this example).
Any help would be greatly appreciated.
I think
[1,4,5,1,5].filter(function(x, n, self) {
return self.indexOf(x) == self.lastIndexOf(x)
})
A probably more efficient hash-based version using underscore:
a =[1, 2, 3, 3, 4, 2, 1, 5]
uniqs = _.chain(a).countBy().pairs().filter(function(x) {
return x[1] == 1
}).pluck(0).value()
or plain javascript:
a = [1, 2, 3, 3, 4, 2, 1, 5]
hash = {}
a.forEach(function(x) {
hash[x] = (Number(hash[x]) || 0) + 1
});
uniq = Object.keys(hash).filter(function(n) {
return hash[n] == 1
});
Note however, that this would convert array values to strings (the result will be ["4","5"]).
If you're happy with the array being sorted, you can also do it like this:
a = [1, 2, 3, 3, 4, 2, 1, 5]
uniq = a.sort().filter(function(x, n, self) {
return x != self[n - 1] && x != self[n + 1];
});
//[4, 5]
The second and third methods have a serious limitation that they only work with primitive values - you cannot "uniquify" an array of objects. The first function works just fine:
x = {x:1}; y = {y:1}; a = [x, y, x, x];
uniq = a.filter(function(x, n, self) {
return self.indexOf(x) == self.lastIndexOf(x)
})
// {"y":1}
For those curious, performance tests (quite inconsistent in different browsers): http://jsperf.com/efficient-unique/2
This works, and is far more efficient that a naive search (O(nlog(n)) rather than O(n^2)), however it does modify the existing array.
var unique = [];
myArray.sort();
for (var i=0, j;i<myArray.length;i = j) {
for (j=i+1;j<myArray.length && myArray[i] === myArray[j]; j++);
if (j == i + 1) {
unique.push(myArray[i]);
}
}
// use unique
As discussed in the comments, you can also utilize an object and achieve an O(n) solution, however the execution time of this approach varies wildly across platforms (sometimes being slower than the above solution, and other times being quicker).
var unique = [], hash = {}, curr;
for (var i=0;i<myArray.length;i++) {
curr = myArray[i];
hash[curr] = (Number(hash[curr]) || 0) + 1;
}
for (var x in hash) {
if (hash[x] === 1) {
unique.push(x);
}
}
// use unique
Try this:-
var arr = [1,4,5,1,5];
var sorted_arr = arr.sort();
var results = [];
for (var i = 0; i < arr.length - 1; i++) {
if (sorted_arr[i + 1] !== sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
You could try using this jquery function:
http://api.jquery.com/jQuery.unique/
"The $.unique() function searches through an array of objects, sorting the array, and removing any duplicate nodes."
Say for instance I have the number 12:
var number = 12;
How could I change that number into something like:
var n = [0,1,2,3,4,5,6,7,8,9,10,11,12];
Someone probably has a jQuery shortcut, but here's a plain JavaScript solution:
var num = 12;
var n = [];
for (var i=0; i <= num; i++) {
n.push(i);
}
As a function:
function num2Array(num) {
var n = [];
for (var i=0; i <= num; i++) {
n.push(i);
}
return n;
}
console.log(num2Array(15));
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
I actually had this function sitting around:
function number_range(beginning, end) {
var numbers = [];
for (; beginning <= end; beginning++) {
numbers[numbers.length] = beginning;
}
return numbers;
}
So if you need to generate more than one of these arrays, it could be useful:
var n = number_range(0, 12);
As for jQuery, well... I don't think that's necessary in this case. (I also don't know of any such function off the top of my head.)
jQuery doesn't have this, but you could use underscore.js:
http://documentcloud.github.com/underscore/#range
_.range([start], stop, [step])
So you could do:
var n = _.range(12);
Or:
var n = _.range(0, 12);
Another JavaScript method
var number = 12, i = 0, n = [];
while( n.push( i++ ), i <= number );
If you need an array just for iterate through you can doing this :
Array(12).fill('');
You just need finding the index from a loop fn to retrieve the current number.