Need Improvisation with this Unique Array Function - javascript

I'm using following code to detect Unique Numbers within Array.
// Array
var sortBp = [ 700, 500, 500, 501, 600];
// Find Unique Numbers
Array.prototype.unique = function(){
var bpAllArrays = this;
var uniqueArrays = [];
for(var i=bpAllArrays.length;i--;){
var uniqueArray = bpAllArrays[i];
if($.inArray( uniqueArray, uniqueArrays )===-1){
uniqueArrays.unshift(uniqueArray);
}
}
return uniqueArrays;
}
// Append Only Unique Numbers
$.each(sortBp.unique(), function(index, value) {
$("body").append(value);
});
This code works fine. Here is working Fiddle : http://jsfiddle.net/ScPbe/
but I want to add another function to detect :
If Very Next Number is present in Array, Remove Higher number & Only append lower Number.
Example : [ 500, 501 ] In this case, I only want 500 to be consider as unique number & not 501
So Final result should look something like :
[ 700, 500, 600]
How can I achieve this ?

Assuming the double values come one after the other (cannot appear anywhere in the array), this solution will be much simpler:
var sortBp = [ 700, 500, 500, 501, 600, 900, 900, 901];
for (var cur, last, i=0; i<sortBp.length; i++) {
cur = sortBp[i];
if (cur === last || cur === last + 1)
continue;
$('body').append(" "+cur);
last = cur;
}
With jQuery.each:
var last;
$.each(sortBp, function(i, cur) {
if (cur === last || cur === last + 1)
return;
$('body').append(" "+cur);
last = cur;
});
Elegant solution using es5's .reduce (might need to be shimmed):
var display = [];
sortBp.reduce(function(last, cur) {
if (cur === last || cur === last+1)
return last;
display.push(cur);
return cur;
}, undefined);
$('body').append(display.join(" "));

Finally, I have comeup with following code. It checks if current value in array is greater than prev value by 1
Here is fiddle : http://jsfiddle.net/ScPbe/5/
// Array
var sortBp = [ 700, 500, 500, 501, 600, 601, 610,612];
// Find Unique Numbers
Array.prototype.unique = function(){
var bpAllArrays = this;
var uniqueArrays = [];
for(var i=bpAllArrays.length;i--;){
var uniqueArray = bpAllArrays[i];
if($.inArray( uniqueArray, uniqueArrays )===-1){
uniqueArrays.unshift(uniqueArray);
}
}
return uniqueArrays;
}
// Append Only Unique Numbers
var arr = sortBp.unique();
$.each(arr, function(index, value) {
// Chect if Current Value > Prev by 1
var prev = arr[index - 1];
if (value - prev !== 1 ) {
$('body').append(" "+value);
}
});

Related

Find Index of element that has no any duplicate in set of array

I have a collection of data here, you can see below.
What I want is to get the index of that element that has a unique value in array.
var setArray = [ false, true, false, false ]
// Sample result will be 1, the index of unique value in array is true
// and has a index of 1
// code here to get the index...
How can I solve this?
var setArray = [ false, true, false, false ]
function singles( array ) {
for( var index = 0, single = []; index < array.length; index++ ) {
if( array.indexOf( array[index], array.indexOf( array[index] ) + 1 ) == -1 ) single.push( index );
};
return single;
};
singles(setArray); //This will return 1
A slightly modified function by ThinkingStiff on this question to suit your needs. Just pass in your array, and it'll return the index value of the unique element! That simple. Let me know how it goes.
Have you tried the following algorithm:
for every item in the array find the index of first occurence and the index of the next occurence. If the index of next occurence is -1, then it is unique.
var setArray = [ false, true, false, false ];
var unique = [];
setArray.forEach(item => {
let firstIndex = setArray.indexOf(item, 0);
let secondIndex = setArray.indexOf(item, firstIndex + 1);
if(secondIndex < 0) {
unique.push(firstIndex);
}
});
See following fiddle for example:
https://jsfiddle.net/yt24ocbs/
This code will return an array of indexes of all unique elements in array. It accepts different types of values: string, number, boolean.
"use strict";
let strings = ["date1", "date", false, "name", "sa", "sa", "date1", 5, "8-()"];
let result = [];
let data = strings.reduce((acc, el) => {
acc[el] = (acc[el] || 0) + 1;
return acc;
}, {});
let keys = Object.keys(data);
for (let i = 0, max = keys.length; i < max; i++) {
if (data[keys[i]] === 1) {
let index = strings.indexOf(keys[i]);
if (index === -1) {
index = strings.indexOf(+keys[i]);
}
if (index === -1) {
index = strings.indexOf(keys[i] === true);
}
result.push(index);
}
}
result.sort( (a, b) => {return a - b});
console.log(result);
You could map the indices for unique values and then filter just the index.
var array = [false, true, false, false],
result = array
.map(function (a, i, aa) { return aa.indexOf(a) === aa.lastIndexOf(a) ? i : -1; })
.filter(function (a) { return ~a; });
console.log(result[0]);
ES6
var array = [false, true, false, false],
result = array
.map((a, i, aa) => aa.indexOf(a) === aa.lastIndexOf(a) ? i : -1)
.filter(a => ~a);
console.log(result[0]);

Count the number of unique occurrences in an array that contain a specific string with Javascript

Here is my javascript array:
arr = ['blue-dots', 'blue', 'red-dots', 'orange-dots', 'blue-dots'];
With Javascript, how can I count the total number of all unique values in the array that contain the string “dots”. So, for the above array the answer would be 3 (blue-dots, orange-dots, and red-dots).
var count = 0,
arr1 = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i].indexOf('dots') !== -1) {
if (arr1.indexOf(arr[i]) === -1) {
count++;
arr1.push(arr[i]);
}
}
}
you check if a certain element contains 'dots', and if it does, you check if it is already in arr1, if not increment count and add element to arr1.
One way is to store element as key of an object, then get the count of the keys:
var arr = ["blue-dots", "blue", "red-dots", "orange-dots", "blue-dots"];
console.log(Object.keys(arr.reduce(function(o, x) {
if (x.indexOf('dots') != -1) {
o[x] = true;
}
return o
}, {})).length)
Try this something like this:
// Create a custom function
function countDots(array) {
var count = 0;
// Get and store each value, so they are not repeated if present.
var uniq_array = [];
array.forEach(function(value) {
if(uniq_array.indexOf(value) == -1) {
uniq_array.push(value);
// Add one to count if 'dots' word is present.
if(value.indexOf('dots') != -1) {
count += 1;
}
}
});
return count;
}
// This will print '3' on console
console.log( countDots(['blue-dots', 'blue', 'red-dots', 'orange-dots', 'blue-dots']) );
From this question, I got the getUnique function.
Array.prototype.getUnique = function(){
var u = {}, a = [];
for(var i = 0, l = this.length; i < l; ++i){
if(u.hasOwnProperty(this[i])) {
continue;
}
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
then you can add a function that counts ocurrences of a string inside an array of strings:
function getOcurrencesInStrings(targetString, arrayOfStrings){
var ocurrencesCount = 0;
for(var i = 0, arrayOfStrings.length; i++){
if(arrayOfStrings[i].indexOf(targetString) > -1){
ocurrencesCount++;
}
}
return ocurrencesCount;
}
then you just:
getOcurrencesInStrings('dots', initialArray.getUnique())
This will return the number you want.
It's not the smallest piece of code, but It's highly reusable.
var uniqueHolder = {};
var arr = ["blue-dots", "blue", "red-dots", "orange-dots", "blue-dots"];
arr.filter(function(item) {
return item.indexOf('dots') > -1;
})
.forEach(function(item) {
uniqueHolder[item] ? void(0) : uniqueHolder[item] = true;
});
console.log('Count: ' + Object.keys(uniqueHolder).length);
console.log('Values: ' + Object.keys(uniqueHolder));
Try this code,
arr = ["blue-dots", "blue", "red-dots", "orange-dots", "blue-dots"];
sample = [];
for (var i = 0; i < arr.length; i++) {
if ((arr[i].indexOf('dots') !== -1) && (sample.indexOf(arr[i]) === -1)){
sample.push(arr[i]);
}
}
alert(sample.length);
var arr = [ "blue-dots", "blue", "red-dots", "orange-dots", "blue-dots" ];
var fArr = []; // Empty array, which could replace arr after the filtering is done.
arr.forEach( function( v ) {
v.indexOf( "dots" ) > -1 && fArr.indexOf( v ) === -1 ? fArr.push( v ) : null;
// Filter if "dots" is in the string, and not already in the other array.
});
// Code for displaying result on page, not necessary to filter arr
document.querySelector( ".before" ).innerHTML = arr.join( ", " );
document.querySelector( ".after" ).innerHTML = fArr.join( ", " );
Before:
<pre class="before">
</pre>
After:
<pre class="after">
</pre>
To put this simply, it will loop through the array, and if dots is in the string, AND it doesn't already exist in fArr, it'll push it into fArr, otherwise it'll do nothing.
I'd separate the operations of string comparison and returning unique items, to make your code easier to test, read, and reuse.
var unique = function(a){
return a.length === 0 ? [] : [a[0]].concat(unique(a.filter(function(x){
return x !== a[0];
})));
};
var has = function(x){
return function(y){
return y.indexOf(x) !== -1;
};
};
var arr = ["blue-dots", "blue", "red-dots", "orange-dots", "blue-dots"];
var uniquedots = unique(arr.filter(has('dots')));
console.log(uniquedots);
console.log(uniquedots.length);

Store count of integers in order using javascript

I have string like the following:
11222233344444445666
What I would like to do is output the number followed the times it was displayed:
112433475163
Question is, I want this to be efficient. I can store this in an object as the following:
1: { id: 1, displayed: 2},
2: { id: 2, displayed: 1},
3: { id: 3, displayed: 2},
etc.
I can access this object and increment displayed.
My issues is, there is no guarantee in the order. I would like to store the keys in the order they are in the string. How do I accomplish the importance of the order in the object?
This is a proposal for run length coding with an array which holds infomation about one charcter and the count of it:
{
"char": "1",
"count": 2
},
var string = "11222233344444445666",
array = function () {
var r = [], o = {};
string.split('').forEach(function (a, i, aa) {
if (a !== aa[i - 1]) {
o[a] = { char: a, count: 0 };
r.push(o[a]);
}
o[a].count++;
});
return r;
}(string);
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');
Quick solution with for loop:
var str = "7771122229933344444445666",
obj = {},
len = str.length,
val = null,
count_str = "",
key = "";
for (var i = 0; i < len; i++) {
val = str[i], key = 'k' + val;
if (!obj[key]) {
obj[key] = {'id': val, 'displayed': 1};
} else {
obj[key].displayed++;
}
}
for (var p in obj) {
count_str += obj[p]['id'] + obj[p]['displayed'];
}
console.log(count_str); // "7312249233475163"
because you have such a small set of distinct numbers, I seen no reason why you can't use a array (yeah it's not super ideal memorywise if you skip values and it becomes sparse, but for such a small subset it won't affect you enough to worry of it). Then you can use (number-1) as the index and increment that number as needed.
var counts = [];
var str = "11222233344444445666";
for(var i in str){
var index = parseInt(str[i])-1
counts[index] = (counts[index]||0)+1;
}
for(var i in counts){
var which = 1+parseInt(i);
var count = counts[i];
console.log("# of " + which +"'s: "+count);
}
https://jsfiddle.net/ga0fqpqn/
note: You shouldn't need the parseInt(i)... just +i should work but I think jsfiddle has a bug with it about it defaulting i to handle like a string.
You could store an additional array with the order of the numbers, which you only append to if the object doesn't yet contain the given number. Then once you're done counting, iterate through that array and output the number and the count from the lookup dictionary.
var chars = "1234576123452345".split("");
var order = [];
var hash = {};
chars.forEach(function(char) {
if (!hash[char]) {
hash[char] = 1;
order.push(char);
} else {
hash[char]++;
}
});
console.log(order.map(function(char) {
return char + hash[char];
}).join(""));
// "12233343537161"

Compare properties of objects stored in array

I have an JavaScript array of this format:
var dimensions = [
{dim: 590, token:'...'},
{dim: 800, token:'.....'},
{dim: 2500, token:'........'}
];
Data in dimensions array is populated dynamically i.e. I' don't know whether it is gonna be zero, one or 50 objects with dim and token properties.
What I need is to pick token from object that have largest value of dim, and smallest value of dim. Anyone have a clue how do I do that?
I suggest to use Array.prototype.reduce(). It returns an object with the min and max object of the array.
var dimensions = [
{ dim: 590, token: '...' },
{ dim: 800, token: '.....' },
{ dim: 2500, token: '........' }
],
result = dimensions.reduce(function (r, a) {
r.min = r.min || a;
r.max = r.max || a;
return {
min: r.min.dim < a.dim ? r.min : a,
max: r.max.dim > a.dim ? r.max : a
};
}, {});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
var dimensions = [
{dim: 590, token:'...'},
{dim: 800, token:'.....'},
{dim: 2500, token:'........'}
];
// Sort the function in ascending order and pick the first and the last element.
var minmax = dimensions.sort(function(a,b){
return a.dim - b.dim;
}).filter(function(el, i){
return i==0 || i==dimensions.length-1;
});
// minmax will have two values, first will be minimum and second will be the largest.
console.log("Smallest: "+minmax[0].token);
console.log("Largest: "+minmax[1].token);
Use sort function to sort the array first and then pick first and last element from array.
dimensions.sort(function(a,b)
{
return a.dim - b.dim
});
var tokenOfSmallest = dimensions[0].token;
var tokenOfLargest = dimensions[dimensions.length - 1].token;
Although most answers provided here are correct, they are not the optimal solutions for your problem (Except Nina Scholz).
Sorting the array via Array.sort() takes a Big-O complexity of O(n*log(n)), but your problem could certainly be solved with a faster, O(n) algorithm.
var dimensions = [
{dim: 590, token:'...'},
{dim: 800, token:'.....'},
{dim: 2500, token:'........'}
];
function getTokenForLargestDim(array)
{
if(array.length === 0) { throw new Error('Empty array'); }
var maxDim = Number.NEGATIVE_INFINITY;
var maxIndex = -1;
for(var i=0; i < array.length; i++) {
var lastDim = maxDim;
if(dimensions[i].dim > maxDim) { maxDim = dimensions[i].dim; maxIndex = i;}
}
return array[maxIndex].token;
}
getTokenForLargestDim(dimensions);
sort the dimensions array first in ascending order and then get smallest and largest token value
dimensions.sort(function(a, b) {
return parseInt(a.dim) - parseInt(b.dim);
});
var smallest = dimensions[ 0 ].token;
var largest = dimensions[ dimensions.length - 1 ].token;
You can reduce your array to find max/min:
var result = dimensions.reduce(function(r, item) {
r.max = !r.max || r.max.dim < item.dim ? item : r.max;
r.min = !r.min || r.min.dim > item.dim ? item : r.min;
return r;
}, {});
console.log(result.max.token);
console.log(result.min.token);

JQuery retriving the next greatest element

in JQuery i m having an array like
(1,2,6,8)
I have already selected the first element that is 1 which i have saved in a JQuery variable
submitterid = 1
On clicking a link I am trying to get the next greatest element in the Array than what I have selected in the submitterid..
How can I achieve this?
Edit:
How to find the last element in this array in the code
var previousId;
$("#previous").click(function (){
index = submitters.indexOf(submitterid),
nextId;
if (index - 1 < submitters.length) {
previousId = submitters[index-1];
} else {
// no ID index
// if i am having an array of 1,2,6,8 after moving to 1 from 8 to 6 - 2-1 i am trying to move to the last element of the array
}
alert(previousId);
});// previousId
Why couldn't you do something like:
var arr = [3, 5, 8, 3].sort(function (a, b) { return a - b; } );
var val = arr.pop();
Any keep popping the array -- saying that the values don't need to stay in the array.
If you are randomly picking values and you need the next highest, then write the appropriate sorting function.
You want a counter:
function counter(arr) {
this.arr = arr;
this.index = 0;
}
counter.prototype.next = function() {
return this.arr[this.index++];
}
You instantiate it and use it like:
var nums = new counter([1,2,3,4,5]);
nums.next() ; => 1
nums.next() ; => 2
nums.next() ; => 3
Actually, there is no need to use any jquery-specific stuff for this, apart from the click event handling, just 'plain javascript' will do;
var myArray = [ 1, 2, 6, 8 ];
var submitterid = 1;
$(function() {
$('a#id').click(function(event) {
event.preventDefault();
var greater = -1;
// loop through array
for (var i in myArray)
// find numbers greater than the specified number
if (i > submitterid)
// find numbers closest to specified number
if (i < greater || greater < 0)
greater = i;
if (greater < 0) {
// no greater value found, do something
} else {
// next biggest value is in variable greater, do something with it
}
});
});
You have to loop through the array.
Try this untested code:
// Your test array.
var arrValues = [ "1", "2", "6", "8" ];
var low = 1;
var high = 2;
// Loop over each value in the array.
$.each( arrValues, function( intIndex, objValue ){
if (objValue > high)
hight = objValue;
if (objValue < high)
if (objValue > low)
low = objValue
});
return low;
If your array is already sorted (see sort method), try this:
var arr = [1,2,6,8],
submitterid = 1,
index = arr.indexOf(submitterid),
nextId;
if (index + 1 < arr.length) {
nextId = arr[index+1];
} else {
// no ID index
}

Categories