Count times a value is repeated in data fetched using REST call - javascript

I'm fetching data from SharePoint using REST, and everything works just fine, except that I would like to count the times the same item appears.
This is the jQuery:
var url = "https:xxxxxxxx/_vti_bin/ListData.svc/RMSD_Tasks?$orderby=TypeOfIssueValue asc,StatusValue desc&$filter=StatusValue ne 'Completed'&groupby=TypeOfIssueValue/StatusValue";
var lastIssue = '';
$.getJSON(url, function (data) {
$('#totalCounter').text(data.d.results.length);
for (var i = 0; i < data.d.results.length; i++) {
var dateReceived = data.d.results[i].DateReceived;
dateReceived = new Date(parseInt(dateReceived.replace("/Date(", "").replace(")/", ""), 10)).toLocaleString('en-US', {
year: 'numeric',
month: 'numeric',
day: '2-digit'
});
var issue = data.d.results[i].TypeOfIssueValue;
console.log(data.d.results[i].TypeOfIssueValue);
if (issue != lastIssue) {
lastIssue = issue;
$('#myDataList').append('' + issue + '<span class="badge">' + issue.length + '</span>');
}
}
});
I need to count how many time a specific TypeOfIssueValue appears. When I see the console it shows exactly what I would like to add to me info:
I just added a issue.length in the badge were I want to insert the number for the sake of just having something there, but I know it won't show what I want. Thanks!

var data = {
d: {
results: [
{ TypeOfIssueValue: '456' },
{ TypeOfIssueValue: '123' },
{ TypeOfIssueValue: '789' },
{ TypeOfIssueValue: '123' }
]
}
};
var filteredItems = data.d.results.filter(function(item){
return item.TypeOfIssueValue == '123';
});
var count = filteredItems.length;
document.getElementById("output").innerHTML = "Number of items with value '123': " + count;
<div id="output"/>

You could first map the TypeOfIssueValue values to a new array and then count each occurence based on this answer.
The code would be :
var a = data.d.results.map(function(issue) {
return issue.TypeOfIssueValue
});
result = {};
for (i = 0; i < a.length; ++i) {
if (!result[a[i]])
result[a[i]] = 0;
++result[a[i]];
}
The result will be an object with property being type of issue and value being the count of each.
Let me know if this makes sense.

Thanks #srinivas. I accepted your response, although I made some modifications, just in case they are useful to someone else.
I added a class to the span badge and added a new array to push the issues:
issuesArray.push(data.d.results[i].TypeOfIssueValue);
$('#myDataList').append('' + issue + '<span class="badge badgeSpan"></span>');
Then I addded a done() to run after the getJSON:
.done(
function(){ var resultado = foo(issuesArray)[1];
console.log(resultado);
var badges = $('.badgeSpan');
for (var j = 0; j < resultado.length; j++){
badges[j].innerHTML = resultado[j];
}
});
Last I made a small modificfation to the function foo() that you provided:
testArray = [];
function foo(arr) {
var a = [], b = [], prev;
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
testArray.push(a,b)
return testArray;
}
This maybe a very unorthodox solution, but it worked for me. Thanks again.

Related

Matching strings don't trigger condition in Javascript

I am trying to do a very simple stock counting app, and display dynamically the stocks for each item. When I try to pair the button with its item, it doesn't work, even though the 2 strings are actually a match.
Here is the faulty function:
socket.on('Stock init', (data) => {
items = data.items;
displayStock(items);
});
function displayStock(items) {
fridgeItem.forEach((fridgeItem) => {
for (let i = 0; i < items.length; i++) {
var databaseProduct = items[i].name;
var databaseQuantity = items[i].chilled.toString();
console.log(fridgeItem.textContent, databaseProduct);
}
if (fridgeItem.textContent === databaseProduct) {
fridgeItem.textContent = databaseProduct + ' ' + databaseQuantity;
} else {
console.log('err');
}
});
}
Answer might be stupid but I can't see it at the moment. Thanks

Count duplicate property values of a nested Javascript object

I'm feeding in information in from an API with the format -
Records = { 0: {fields: {name: "nameExample" place: "placeExample"} }
{1: {fields: {name: "nameExample" place: "placeExample"} }
etc etc
I'm looking for a way to count duplicates of the 'place' field in the format: Scotland(4), London(6) etc. where the number is the amount of times it repeats.
The closest I've got as of yet is counting the letters in each place name, but I'm not sure what I'm doing wrong. I think if I can get them in the same array then it would be simple, but when I tried to do that it put each place in a different array.
Also must be vanilla javaScript, no jQuery. Many thanks!
var URL = new Array();
URL[0] = "https://www.vam.ac.uk/api/json/museumobject/search?q=a&limit=45";
URL[1] = "https://www.vam.ac.uk/api/json/museumobject/search?q=a&limit=45&offset=45";
URL[2] = "https://www.vam.ac.uk/api/json/museumobject/search?q=a&limit=45&offset=90";
var nRequest = new Array();
for (var i=0; i<3; i++){
(function(i) {
nRequest[i] = new XMLHttpRequest();
nRequest[i].open("GET", URL[i], true);
nRequest[i].onreadystatechange = function (oEvent) {
if (nRequest[i].readyState === 4) {
if (nRequest[i].status === 200) {
var data = JSON.parse(nRequest[i].responseText);
var url = 'http://media.vam.ac.uk/media/thira/collection_images/';
for (let key in data.records) {
let value = data.records[key];
let image = value.fields.primary_image_id;
let res = image.substr(0, 6);
document.querySelector(".map").innerHTML += '<div class="' + value.fields.place + ' map"> ' + value.fields.place + ' <br> </div>';
}
} else {
console.log("Error", nRequest[i].statusText);
}
}
//
};
nRequest[i].send(null);
})(i);
};
If thats the data structure you can solve it like so:
const Records = [
{fields: {name: "nameExample", place: "placeExample"}},
{fields: {name: "nameExample", place: "placeExample"}}
];
const result = Records.reduce((acc, {fields}) => {
if(acc[fields.place]) acc[fields.place]++;
else acc[fields.place] = 1;
return acc;
}, {})
console.log(result);
You can use the reduce function to convert the array data.records to an object with the place as key and number of occurrences as value.
data.records.reduce((accum, currVal) => {
if (!(currVal.fields.place in accum)){
accum[currVal.fields.place] = 0;
}
accum[currVal.fields.place] += 1;
return accum;
}, {});

Hamsters.js Returns Erroneous Results

Hamsters holds a great promise to my work. I work with matrices and vectors in JavaScript. Recently I stumbled upon the JS Multithreading library Hamsters and read through the introduction at GitHub. Unfortunately I cannot get the code to work right - usually I don't get any errors but I get wrong or missing results.... It is extremely important that I get correct results all the time, else I'll have to abandon this approach. Am sure you can help me figure what's wrong. See sample code below. The Vanilla output is perfectly what I expect but Hamsters doesn't actually return any results, else when/if it does I get erroneous ones e.g. 0.05681.324987324.602 or similar.
var vec = [0.19560742625827293, 0.5969056836197602, 0.7781011114598421, -1.4801188964351797e-16, 0];
try {
var i, dotprod = 0, cnt = vec.length;
for (i = 0; i < cnt; i+=1) {
dotprod += (vec[i] * vec[i]);
}
console.log("vanilla:" + dotprod);
var params = {'array': vec};
hamsters.run(params, function () {
var arr = params.array;
var dotprod = 0;
arr.forEach(function (item) {
dotprod += (item * item);
});
console.log("each-thread:" + dotprod);
rtn.data = dotprod;
}, function (output) {
console.log("threads:" + output);
}, hamsters.maxThreads, true, 'Float32');
} catch (err) {
console.log(err);
}
I've also tried the code below, with the realization that the 'aggregation' means that each thread appends it's subarray into the final output... Still the results are not reliable and even straight out wrong. I have tried it on a matrix this time. The single-threaded Vanilla version still does it perfectly right.
var matrix = [
[0.19560742625827293, 0.5969056836197602, 0.7781011114598421, -1.4801188964351797e-16, 0],
[0.19560742625827268, 0.5969056836197597, -0.7781011114598423, 0, -4.9920006143177403e-17],
[0.6420441782236752, -0.28992643646108446, -0.06100766058506449, 0, 0.7071067811865475],
[0.3705351281738152, 0.6896295583459146, 0.6221854956882503, 0, 9.114104478471581e-17]
];
var i;
for (i = 0; i < matrix.length; i += 1) {
try {
var j, dotprod = 0, matrix_row = matrix[i];
for (j = 0; j < matrix_row.length; j += 1) {
dotprod += (matrix_row[j] * matrix_row[j]);
}
console.log("Vanilla-output:" + dotprod);
var params = {'array': matrix_row};
hamsters.run(params, function () {
var arr = params.array;
var dotprod = [];
arr.forEach(function (item) {
dotprod.push(item * item);
});
//console.log("each-thread:" + dotprod);
rtn.data = dotprod;
}, function (results) {
var output = 0;
results.forEach(function (item) {
output += item;
});
console.log("Hamsters-output:" + output);
}, hamsters.maxThreads, true, 'Float32');
} catch (err) {
console.log(err);
}
}

User:index is undefined?

I have made a localStorage with a user_name login and i have parsed the string of my JSON data (entry) to a plain object.
But if I try to console log entry.username i get my stored users but also get a "undefined"?
I suspect that is my User:index code that is messing up the entry.user_name?
var User = {
index: window.localStorage.getItem("User:index"),
$form: document.getElementById("userReg"),
$button_register: document.getElementById("registerUser"),
$button_login: document.getElementById("logIN"),
init: function() {
// initialize storage index
if (!User.index) {
window.localStorage.setItem("User:index", User.index = 1);
}
User.$form.addEventListener("submit", function(event) {
var entry = {
id: parseInt(this.id_entry.value),
user_name: this.user_name.value,
};
if (entry.id == 0) {
User.storeAdd(entry);
}
}, true);
User.$button_login.addEventListener("click", function(entry) {
for (var i = 0, len = localStorage.length; i < len; ++i) {
var key = localStorage.key(i);
var value = localStorage[key];
entry = JSON.parse(window.localStorage.getItem(key));
console.log(entry.user_name);
}
if (document.getElementById("firstName").value == entry.user_name) {
alert("You have logged in");
} else {
document.getElementById("negative").innerHTML = "Username does not match"
}
}, true);
},
storeAdd: function(entry) {
entry.id = User.index;
window.localStorage.setItem("User:index", ++User.index);
window.localStorage.setItem("User:" + entry.id, JSON.stringify(entry));
},
};
User.init();
The issue is the data in localStorage. Your login function assumes that all entries stored in localStorage will be of your User entry type. But when you start storing other things, you have no checking to confirm the type is what you expect.
Here:
for (var i = 0, len = localStorage.length; i < len; ++i) {
var key = localStorage.key(i);
var value = localStorage[key];
entry = JSON.parse(window.localStorage.getItem(key));
console.log(entry.user_name);
}
The line that is actually failing is: entry = JSON.parse(window.localStorage.getItem(key)); because at the end of the loop, the type in localStorage is User:index, not User:3.
If you plan on having more things in localStorage, you should add a check in your loop, such as this:
for (var i = 0; i < localStorage.length; ++i) {
var key = localStorage.key(i);
var reg = new RegExp("User\:\\d+$");
//Only process user entries
if(reg.test(key)) {
var value = localStorage[key];
entry = JSON.parse(window.localStorage.getItem(key));
console.log(entry.user_name);
console.log(entry);
} // end if
}
Here is a fiddle: http://jsfiddle.net/xDaevax/Lo63vftt/
Disclaimer: I changed some other things to in order for it to work more efficiently for a fiddle, you can ignore the other changes I made.
You are right it is the User:index causing this issue. You can fix it with the following code.
for(var i = 1; i < User.index; i++) {
var key = "User:" + i;
var entry = JSON.parse(localStorage[key]);
console.log("entry : ", key, entry);
...
http://jsfiddle.net/yv04x4mw/6/
May I also recommend not creating accounts this way (unless you have a good reason), also use a JavaScript library like jQuery.

Error while manipulating values from textarea

I am Bobi from Macedonia, and I stumbled upon one ugly problem with
my JavaScript/jQuery code.
I want to enter some values in my textarea, and then according to the specific formula
those values need to be calculated and the result need to be presented with alert.
Here is my code...
//First this is my formula
function calc(data) {
ret = [];
for(var i = 0; i < data.length; i++) {
ret[i] = (3.5 + data[i] + 0.5 * (data[i] - 3));
}
return ret;
}
//Now, taking values from the text area using valHooks
$.valHooks.textarea = {
get: function(elem) {
return elem.value.replace( /\r?\n/g, "\r\n" );
}
};
$('button').click(function() {
//in this step the values are successfully taken from the textarea
var sample = {};
sample.data = $('textarea').val();
//alert(sample.data); <-- this works fine
var result = {};
result.data = calc(sample.data); //but here seems to be the problem
alert(result.data); //the alert shows some gibberish values
So for example, if I enter these values 1.6, 3.9, 3.3, 4.0, 2.5, 2.8...
The alert need to show these calculated values: 4.4, 7.85, 6.95, 8.0, 5.75, 6.2...
Here is also jsfiddle
http://jsfiddle.net/Avramoski/skqG4/
I know that I am missing something small, but God knows what it is...
Please help! :(
do the following three changes as i noted.. and enjoy codding.. :)
function calc(data) {
ret = [];
for(var i = 0; i < data.length; i++) {
data[i] = parseFloat(data[i]); // here u want to parse ur string to float
ret[i] = (3.5 + data[i] + 0.5 * (data[i] - 3));
ret[i] = Math.round(ret[i] * 100) / 100; // this code for get rounded answer like exactly u needed
}
return ret;
}
$.valHooks.textarea = {
get: function(elem) {
return elem.value.replace( /\r?\n/g, "\r\n" );
}
};
$('button').click(function() {
var sample = {};
sample.data = $('textarea').val();
sample.data = sample.data.split(","); //textarea value transferring to array
//alert(sample.data);
var result = {};
result.data = calc(sample.data);
alert(result.data);
} // and dont miss this curly bracket :D
Click FIDDLE link to demo result.
You must check parseFloat number was valid.
$(function () {
function calc(data) {
ret = [];
var res=data.split(',');
for(var i = 0; i < res.length; i++) {
var parseNumber=parseFloat(res[i]);
ret[i] = (3.5 + parseNumber + 0.5 * (parseNumber - 3)).toFixed(2);
}
return ret;
}
//Taking values from the text area using valHooks
$.valHooks.textarea = {
get: function(elem) {
return elem.value.replace( /\r?\n/g, "\r\n" );
}
};
$('button').click(function() {
var result = {};
result.data = calc(sample.data);
alert(result.data);
});
});

Categories

Resources