How can i ignore duplicate values in if statement? - javascript

var availableMarketGroups = {};
angular.forEach(function (market) {
if (availableMarketGroups[market.group_id]) { // market.group_id is not sorted id
availableMarketGroups[market.group_id].count++;
}
});
market.group_id - number ,not sorted, and sometimes its duplicates
availableMarketGroups[market.group_id].count - its length
Lets see the image for more info.
The numbers of the market groups don't represent real amount of markets.
availableMarketGroups[market.group_id].count show - 15 ,but in real it should be 5 (5 groups) ,because market.group_id is duplicates.
How can i ignore duplicated market.group_id values in if statement ?

var availableMarketGroups = {};
var groupsProcessed = [];
angular.forEach(availableMarketGroups, function(marketGroup) {
if (groupsProcessed.indexOf(marketGroup.group_id) < 0) {
groupsProcessed.push(marketGroup.group_id);
availableMarketGroups[market.group_id].count++;
}
});

Answer for counting unique array elements is to make a function as given below.
var counts = {};
for (var i = 0; i < arr.length; i++) {
counts[arr[i]] = 1 + (counts[arr[i]] || 0);
}
It will return the unique counts of elements in the array.
Reference : Count unique elements in array without sorting

Hard to say without your data. Generally speaking, you should be able to reduce this down to the unique Set of group_ids:
const uniqueGroups = markets.reduce(function(set, market) {
if (!set.has(market.group_id)) {
set.add(market.group_id);
}
return set;
}, new Set());
console.log('Unique group count: ', uniqueGroups.size);

You can use underscore:
var newObj = _.uniq(market, function(p){ return p.group_id; });

Related

Return first value of array based on second value [duplicate]

This question already has answers here:
How to add same elements to javascript array n times
(4 answers)
Closed 4 years ago.
I've been trying to figure this problem out for a while but I'm at a blank. Here's what I have so far:
var repeatNumbers = function(data) {
var repeated = [];
for ( var x = 0; x < data.length; x++){
var unit = data[x][0]
var quant = data[x][1]
for(var i = quant; i > 0; i--){
repeated.push(unit);
repeated.join(',');
}
return repeated;
}
};
console.log(repeatNumbers([1, 10]));
Basically I'm trying to repeat the first number of the array based off of the second value. Any insight would be greatly appreciated thank you! :)
You don't need to loop over your array if you only have two numbers, where the first number (at index 0) is the number you want to repeat, and the second number is the number of times you want to repeat that number (index 1).
Once you have the number of times you wish to repeat the number, you can simply use a for loop to enter the number into your repeated array that number of times.
See working example below (read code comments for further explanation):
var repeatNumbers = function(data) {
var repeated = []
var toRepeat = data[0]; // get the first number in the array
var times = data[1]; // get the second number in the array
// loop the number of times you want to repeat the number:
for(var i = 0; i < times; i++) {
repeated.push(toRepeat); // push the number you wish to repeat into the repeated array
}
return repeated.join(); // return the joined array (as a string - separated by commas)
}
console.log(repeatNumbers([1, 10]));
If I understand your question correctly, you want the function repeatNumbers() to return an array with the first element in the passed array replicated by the second element in the passed array.
To achieve that, you could do the following:
var repeatNumbers = function(data) {
// Extract the "value" to be repeated, and the "repeated" value
// that will control the number of "value" items in result array
var value = data[0];
var repeated = data[1];
var result = []
// Loop over repeated range, and push value into the result array
for (var i = 0; i < repeated; i++) {
result.push(value);
}
// Result result array
return result;
};
console.log(repeatNumbers([1, 10]));
Or, if you don't need to support IE, a more consise approach would be:
var repeatNumbers = function(data) {
var value = data[0];
var repeated = data[1];
return (new Array(repeated).fill(value));
};
console.log(repeatNumbers([1, 10]));

Accessing indexes of a string inside an array and taking the sum

Ok so I am trying to access each individual number in the strings inside of this array.
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'];
var str = "";
for (i=0; i<array.length; i++) {
str = array[i];
}
The problem is that this is the output: '999-992-1313'
and not the first element array[0]: '818-625-9945'
When I try doing a nested for loop to go through each element inside the string I am having trouble stating those elements.
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'];
for (i=0; i<array.length; i++) {
for (j=0; j<array[i].length; j++) {
console.log(array[i][j]);
}
}
I do not know how to access each individual number inside of the string array[i]. I would like to find a way to make a counter such that if I encounter the number '8' I add 8 to the total score, so I can take the sum of each individual string element and see which number has the highest sum.
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'];
for (i=0; i<array.length; i++) {
for (j=0; j<array[i].length; j++) {
if (array[i](j).indexOf('8') !== -1) {
// add one to total score
// then find a way to increase the index to the next index (might need help here also please)
}
}
}
Mabe this works for you. It utilized Array.prototype.reduce(), Array.prototype.map() and String.prototype.split().
This proposal literates through the given array and splits every string and then filter the gotten array with a check for '8'. The returned array is taken as count and added to the return value from the former iteration of reduce - and returned.
var array = ['818-625-9945', '999-992-1313', '888-222-2222', '999-123-1245'],
score = array.reduce(function (r, a) {
return r + a.split('').filter(function (b) { return b === '8'; }).length;
}, 0);
document.write('Score: ' + score);
A suggested approach with counting all '8' on every string:
var array = ['818-625-9945', '999-992-1313', '888-222-2222', '999-123-1245'],
score = array.map(function (a) {
return a.split('').filter(function (b) { return b === '8'; }).length;
});
document.write('Score: ' + score);
Actually rereading your question gave me a better idea of what you want. You simply want to count and retrieve the number of 8's per string and which index in your array conforms with this maximum 8 value. This function retrieves the index where the value was found in the array, how many times 8 was found and what is the string value for this result. (or returns an empty object in case you give in an empty array)
This you could easily do with:
'use strict';
var array = ['818-625-9945', '999-992-1313', '888-222-2222', '999-123-1245'];
function getHighestEightCountFromArray(arr) {
var max = 0,
result = {};
if (arr && arr.forEach) {
arr.forEach(function(value, idx) {
var cnt = value.split('8').length;
if (max < cnt) {
// found more nr 8 in this section (nl: cnt - 1)
max = cnt;
// store the value that gave this max
result = {
count: cnt - 1,
value: value,
index: idx
};
}
});
}
return result;
}
console.log(getHighestEightCountFromArray(array));
The only thing here is that when an equal amount of counts is found, it will still use the first one found, here you could decide which "maximum"
should be preferred(first one in the array, or the newest / latest one in the array)
OLD
I'm not sure which sums you are missing, but you could do it in the following way.
There I first loop over all the items in the array, then I use the String.prototype.split function to split the single array items into an array which would then contain ['818', '625', '9945']. Then for each value you can repeat the same style, nl: Split the value you are receiving and then loop over all single values. Those then get convert to a number by using Number.parseInt an then all the values are counted together.
There are definitelly shorter ways, but this is a way how you could do it
'use strict';
var array = ['818-625-9945','999-992-1313','888-222-2222','999-123-1245'],
sumPerIndex = [],
totalSum = 0;
array.forEach(function(item, idx) {
var values = item.split('-'), subArray = [], itemSum = 0;
values.forEach(function(value) {
var singleItems = value.split(''),
charSum = 0;
singleItems.forEach(function(char) {
charSum += parseInt(char);
});
itemSum += charSum;
subArray.push(charSum);
console.log('Sum for chars of ' + value + ' = ' + charSum);
});
sumPerIndex.push(subArray);
totalSum += itemSum;
console.log('Sum for single values of ' + item + ' = ' + itemSum);
});
console.log('Total sum of all elements: ' + totalSum);
console.log('All invidual sums', sumPerIndex);

string occurrences in a string

I'm am working on a script to count the number of times a certain string (in this case, coordinates) occur in a string. I currently have the following:
if (game_data.mode == "incomings") {
var table = document.getElementById("incomings_table");
var rows = table.getElementsByTagName("tr");
var headers = rows[0].getElementsByTagName("th");
var allcoord = new Array(rows.length);
for (i = 1; i < rows.length - 1; i++) {
cells = rows[i].getElementsByTagName("td");
var contents = (cells[1].textContent);
contents = contents.split(/\(/);
contents = contents[contents.length - 1].split(/\)/)[0];
allcoord[i - 1] = contents
}}
So now I have my variable allcoords. If I alert this, it looks like this (depending on the number of coordinates there are on the page):
584|521,590|519,594|513,594|513,590|517,594|513,592|517,590|517,594|513,590|519,,
My goal is that, for each coordinate, it saves how many times that coordinate occurs on the page. I can't seem to figure out how to do so though, so any help would be much appreciated.
you can use regular expression like this
"124682895579215".match(/2/g).length;
It will give you the count of expression
So you can pick say first co-ordinate 584 while iterating then you can use the regular expression to check the count
and just additional information
You can use indexOf to check if string present
I would not handle this as strings. Like, the table, is an array of arrays and those strings you're looking for, are in fact coordinates. Soooo... I made a fiddle, but let's look at the code first.
// Let's have a type for the coordinates
function Coords(x, y) {
this.x = parseInt(x);
this.y = parseInt(y);
return this;
}
// So that we can extend the type as we need
Coords.prototype.CountMatches = function(arr){
// Counts how many times the given Coordinates occur in the given array
var count = 0;
for(var i = 0; i < arr.length; i++){
if (this.x === arr[i].x && this.y === arr[i].y) count++;
}
return count;
};
// Also, since we decided to handle coordinates
// let's have a method to convert a string to Coords.
String.prototype.ToCoords = function () {
var matches = this.match(/[(]{1}(\d+)[|]{1}(\d+)[)]{1}/);
var nums = [];
for (var i = 1; i < matches.length; i++) {
nums.push(matches[i]);
}
return new Coords(nums[0], nums[1]);
};
// Now that we have our types set, let's have an array to store all the coords
var allCoords = [];
// And some fake data for the 'table'
var rows = [
{ td: '04.shovel (633|455) C46' },
{ td: 'Fruits kata misdragingen (590|519)' },
{ td: 'monster magnet (665|506) C56' },
{ td: 'slayer (660|496) C46' },
{ td: 'Fruits kata misdragingen (590|517)' }
];
// Just like you did, we loop through the 'table'
for (var i = 0; i < rows.length; i++) {
var td = rows[i].td; //<-this would be your td text content
// Once we get the string from first td, we use String.prototype.ToCoords
// to convert it to type Coords
allCoords.push(td.ToCoords());
}
// Now we have all the data set up, so let's have one test coordinate
var testCoords = new Coords(660, 496);
// And we use the Coords.prototype.CountMatches on the allCoords array to get the count
var count = testCoords.CountMatches(allCoords);
// count = 1, since slayer is in there
Use the .indexOf() method and count every time it does not return -1, and on each increment pass the previous index value +1 as the new start parameter.
You can use the split method.
string.split('517,594').length-1 would return 2
(where string is '584|521,590|519,594|513,594|513,590|517,594|513,592|517,590|517,594|513,590|519')

How to count the array from specific JSON object value?

here is my javascript:
var json = '{"GetReportIdResult":[{"bulan":"4","total":"1728","type":"CHEESE1K","uang":"8796383"},{"bulan":"4","total":"572476","type":"ESL","uang":"5863408410"},{"bulan":"4","total":"33507","type":"WHP","uang":"235653242"},{"bulan":"5","total":"4761","type":"CHEESE1K","uang":"134877865"},{"bulan":"5","total":"245867","type":"UHT","uang":"1446787280"},{"bulan":"5","total":"47974","type":"WHP","uang":"631929807"},{"bulan":"6","total":"5762","type":"CHEESE1K","uang":"293393832"},{"bulan":"6","total":"236803","type":"UHT","uang":"2219506085"},{"bulan":"6","total":"24853","type":"WHP","uang":"386175022"}]}';
obj = JSON.parse(json);
var arrayobj = obj.GetReportIdResult.length;
alert (arrayobj);
I want to count how many type in the same bulan value, (e.g. there are 3 type = CHEESE1K, UHT, and ESL in bulan = 4)
how to do that?
There's still a typo in your JSON: you've got two commas in a row between the first two "bulan":"6" objects. But assuming you fix that...
If you're asking how to count distinct types for a particular bulan value you can do something like this:
function countTypesForBulan(resultArray, bulanVal) {
var i,
types,
count = 0;
for (i=0, types = {}; i < resultArray.length; i++)
if (resultArray[i].bulan === bulanVal && !types[resultArray[i].type]) {
types[resultArray[i].type] = true;
count++;
}
return count;
}
console.log( countTypesForBulan(obj.GetReportIdResult, "4") ); // logs 3
The above loops through the array looking for a particular bulan value, and when it finds one it checks if it has already seen the associated type - if not, it adds it to the types object and increments the counter.
Demo: http://jsfiddle.net/pAWrT/
First of all, put the JSON into a string,
else your example code wont work.
var json = '{"GetReportIdResult":[{"bulan":"4","total":"1728","type":"CHEESE1K","uang":"8796383"},{"bulan":"4","total":"572476","type":"ESL","uang":"5863408410"},{"bulan":"4","total":"33507","type":"WHP","uang":"235653242"},{"bulan":"5","total":"4761","type":"CHEESE1K","uang":"134877865"},{"bulan":"5","total":"245867","type":"UHT","uang":"1446787280"},{"bulan":"5","total":"47974","type":"WHP","uang":"631929807"},{"bulan":"6","total":"5762","type":"CHEESE1K","uang":"293393832"},,{"bulan":"6","total":"236803","type":"UHT","uang":"2219506085"},{"bulan":"6","total":"24853","type":"WHP","uang":"386175022"}]}';
Then,
Iterate with for and count in a variable or a hashmap.
Since GetReportIdResult is an array, you can:
for( var i : obj.GetReportIdResult ){
obj.GetReportIdResult[i] ... // Use at will.
This will give you a map object which will contain the count for each bulan value. For example, map['4'].count will return 3.
var i, row, arr = obj.GetReportIdResult, map = {};
for (i = 0; i < arr.length; i++) {
row = arr[i];
map[row.bulan] = map[row.bulan] || {count: 0};
if (map[row.bulan][row.type] === undefined) {
map[row.bulan][row.type] = row.type;
map[row.bulan]['count'] += 1;
}
}
console.log (JSON.stringify(map));​
JSFiddle here.

math random number without repeating a previous number

Can't seem to find an answer to this, say I have this:
setInterval(function() {
m = Math.floor(Math.random()*7);
$('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);
How do I make it so that random number doesn't repeat itself. For example if the random number is 2, I don't want 2 to come out again.
There are a number of ways you could achieve this.
Solution A:
If the range of numbers isn't large (let's say less than 10), you could just keep track of the numbers you've already generated. Then if you generate a duplicate, discard it and generate another number.
Solution B:
Pre-generate the random numbers, store them into an array and then go through the array. You could accomplish this by taking the numbers 1,2,...,n and then shuffle them.
shuffle = function(o) {
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
var randorder = shuffle([0,1,2,3,4,5,6]);
var index = 0;
setInterval(function() {
$('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300);
}, 300);
Solution C:
Keep track of the numbers available in an array. Randomly pick a number. Remove number from said array.
var randnums = [0,1,2,3,4,5,6];
setInterval(function() {
var m = Math.floor(Math.random()*randnums.length);
$('.foo:nth-of-type('+(randnums[m])+')').fadeIn(300);
randnums = randnums.splice(m,1);
}, 300);
You seem to want a non-repeating random number from 0 to 6, so similar to tskuzzy's answer:
var getRand = (function() {
var nums = [0,1,2,3,4,5,6];
var current = [];
function rand(n) {
return (Math.random() * n)|0;
}
return function() {
if (!current.length) current = nums.slice();
return current.splice(rand(current.length), 1);
}
}());
It will return the numbers 0 to 6 in random order. When each has been drawn once, it will start again.
could you try that,
setInterval(function() {
m = Math.floor(Math.random()*7);
$('.foo:nth-of-type(' + m + ')').fadeIn(300);
}, 300);
I like Neal's answer although this is begging for some recursion. Here it is in java, you'll still get the general idea. Note that you'll hit an infinite loop if you pull out more numbers than MAX, I could have fixed that but left it as is for clarity.
edit: saw neal added a while loop so that works great.
public class RandCheck {
private List<Integer> numbers;
private Random rand;
private int MAX = 100;
public RandCheck(){
numbers = new ArrayList<Integer>();
rand = new Random();
}
public int getRandomNum(){
return getRandomNumRecursive(getRand());
}
private int getRandomNumRecursive(int num){
if(numbers.contains(num)){
return getRandomNumRecursive(getRand());
} else {
return num;
}
}
private int getRand(){
return rand.nextInt(MAX);
}
public static void main(String[] args){
RandCheck randCheck = new RandCheck();
for(int i = 0; i < 100; i++){
System.out.println(randCheck.getRandomNum());
}
}
}
Generally my approach is to make an array containing all of the possible values and to:
Pick a random number <= the size of the array
Remove the chosen element from the array
Repeat steps 1-2 until the array is empty
The resulting set of numbers will contain all of your indices without repetition.
Even better, maybe something like this:
var numArray = [0,1,2,3,4,5,6];
numArray.shuffle();
Then just go through the items because shuffle will have randomized them and pop them off one at a time.
Here's a simple fix, if a little rudimentary:
if(nextNum == lastNum){
if (nextNum == 0){nextNum = 7;}
else {nextNum = nextNum-1;}
}
If the next number is the same as the last simply minus 1 unless the number is 0 (zero) and set it to any other number within your set (I chose 7, the highest index).
I used this method within the cycle function because the only stipulation on selecting a number was that is musn't be the same as the last one.
Not the most elegant or technically gifted solution, but it works :)
Use sets. They were introduced to the specification in ES6. A set is a data structure that represents a collection of unique values, so it cannot include any duplicate values. I needed 6 random, non-repeatable numbers ranging from 1-49. I started with creating a longer set with around 30 digits (if the values repeat the set will have less elements), converted the set to array and then sliced it's first 6 elements. Easy peasy. Set.length is by default undefined and it's useless that's why it's easier to convert it to an array if you need specific length.
let randomSet = new Set();
for (let index = 0; index < 30; index++) {
randomSet.add(Math.floor(Math.random() * 49) + 1)
};
let randomSetToArray = Array.from(randomSet).slice(0,6);
console.log(randomSet);
console.log(randomSetToArray);
An easy way to generate a list of different numbers, no matter the size or number:
function randomNumber(max) {
return Math.floor(Math.random() * max + 1);
}
const list = []
while(list.length < 10 ){
let nbr = randomNumber(500)
if(!list.find(el => el === nbr)) list.push(nbr)
}
console.log("list",list)
I would like to add--
var RecordKeeper = {};
SRandom = function () {
currTimeStamp = new Date().getTime();
if (RecordKeeper.hasOwnProperty(currTimeStamp)) {
RecordKeeper[currTimeStamp] = RecordKeeper[currTimeStamp] + 1;
return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
}
else {
RecordKeeper[currTimeStamp] = 1;
return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
}
}
This uses timestamp (every millisecond) to always generate a unique number.
you can do this. Have a public array of keys that you have used and check against them with this function:
function in_array(needle, haystack)
{
for(var key in haystack)
{
if(needle === haystack[key])
{
return true;
}
}
return false;
}
(function from: javascript function inArray)
So what you can do is:
var done = [];
setInterval(function() {
var m = null;
while(m == null || in_array(m, done)){
m = Math.floor(Math.random()*7);
}
done.push(m);
$('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);
This code will get stuck after getting all seven numbers so you need to make sure it exists after it fins them all.

Categories