Find how many times "Index" appers in array - javascript

I'm trying to find out if "Index" exist in my array, and second then count how many time it does appear.
Nothing of what I'm trying is working, this is the best attempt i've made, but cant turn my head around this.
var arr = {"__metadata":{"id":"a5e55ca2-c574-434e-8ec3-1b9cd4595bcb","uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)","etag":"\"2\"","type":"SP.Data.SalesListItem"},"FirstUniqueAncestorSecurableObject":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/FirstUniqueAncestorSecurableObject"}},"RoleAssignments":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/RoleAssignments"}},"Activities":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/Activities"}},"AttachmentFiles":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/AttachmentFiles"}},"ContentType":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/ContentType"}},"GetDlpPolicyTip":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/GetDlpPolicyTip"}},"FieldValuesAsHtml":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/FieldValuesAsHtml"}},"FieldValuesAsText":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/FieldValuesAsText"}},"FieldValuesForEdit":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/FieldValuesForEdit"}},"File":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/File"}},"Folder":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/Folder"}},"ParentList":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/ParentList"}},"Properties":{"__deferred":{"uri":"https://lavanet.sharepoint.com/sites/devcla/_api/Web/Lists(guid'cc4de542-1c06-4f53-b787-b8a2d42fe21e')/Items(1)/Properties"}},"FileSystemObjectType":0,"Id":1,"ServerRedirectedEmbedUri":null,"ServerRedirectedEmbedUrl":"","ContentTypeId":"0x010048CF0CAB992F7B409B79C034586FFB7E","Title":"Test data 1","Date":"2017-01-01T08:00:00Z","Index":20,"Index2":15,"ID":1,"Modified":"2017-04-18T12:27:19Z","Created":"2017-02-03T10:02:10Z","AuthorId":17,"EditorId":17,"OData__UIVersionString":"1.0","Attachments":false,"GUID":"d87fa9d2-c81e-4dfd-b568-c8a300fc12d8"}
function containsObject(obj, list) {
var x;
for (x in list) {
if (list.hasOwnProperty(x) && list[x] === obj) {
return true;
}
}
return false;
}
console.log(containsObject("index", arr));
Would love if someone could help a bit

If you would like to count both if key and/or value of prop === index and not bother of case-sensitivity, then you can try something like this.
function containsObject(obj, list) {
var cnt = 0;
for (var x in list) {
var val = list.hasOwnProperty(x) && list[x] ? list[x].toString() : '';
if (x.toLowerCase() === obj.toLowerCase() ||
val.toLowerCase() === obj.toLowerCase()) {
cnt++;
}
}
return cnt;
}

Related

Find duplicates in array JavaScript

So I'm working on a simple JavaScript web-based game. The goal is to guess a X digit random number. This means the random number can be 4, 5 digits up to whatever you want. You can actually play the game at www.juegodescifralo.com , (it's in Spanish, sorry about that).
The user inputs a number that is stored as an array. The random number is also generated as an array. Individual numbers in both arrays can be repeated.
There are three types of possible "values/numbers": the "good" ones are the numbers you chose that are in the same position as the ones in the random array. So for example:
Random array is: 1457
User input is: 6851
Number 5 is a "good" number, since it's in the same position. Then there are the second type of "values", which are "regular". This means they are inside the random number but not in the same position. In this example, number 1 would be a "regular" value. And the third type is the "bad" ones, which are not even inside the random array.
The function I've developed is as follows:
function checkNumbers(randomArray, myArray, good, regular, bad) {
for (var x = 0; x < randomArray.length; x++) {
var posRepetido = randomArray.indexOf(myArray[x]); //Is current number inside random array?
if (posRepetido == -1) { //It's not inside
console.log("number " + myArray[x] + "is not inside");
bad++;
} else { //It's inside
regular++;
if (myArray[x] == randomArray[x]) { //If it's the same number...
console.log("number " + myArray[x] + "is in the correct position");
good++;
regular--;
} else { //If it's not the same number
if (randomArray[posRepetido] != myArray[posRepetido]) {
console.log("number " + myArray[x] + "is inside but not in the same position");
} else {
console.log("number " + myArray[x] + "is not inside");
}
}
}
}
var obj = { //Return object for accessing later, to show feedback to the user.
good: good,
regular: regular,
bad: bad
};
return obj;
}
The code is a bit buggy. When there are duplicates in the random array, and one of them is marked as good, then the other one (even if it exists in user input) will be set as bad, not as regular as it should.
The thing becomes even more complicated since you should be able to play against any amount of digits. So I should be able to guess a 20 digit number without "problems".
You can play by yourself at www.juegodescifralo.com
How can I go about this? Any ideas how can I access array data more easily? Thank you very much!
Rather than indexOf comparisons against -1 and checks of myArray[x], it would probably be a lot easier to use includes and array methods such as forEach for better abstraction. All you really need is an if, an else if, and an else. For example:
function checkNumbers(randomArray, userArray, good=0, regular=0, bad=0) {
userArray.forEach((guess, i) => {
if (guess === randomArray[i]) good++;
else if (randomArray.includes(guess)) regular++;
else bad++;
});
return { good, regular, bad };
}
// 4 good
console.log(checkNumbers(
'1234'.split(''),
'1234'.split(''),
));
// 4 good, 2 bad
console.log(checkNumbers(
'1234'.split(''),
'123456'.split(''),
));
// 4 good, 2 regular
console.log(checkNumbers(
'1234'.split(''),
'123412'.split(''),
));
// all regular:
console.log(checkNumbers(
'123456789123456789'.split(''),
'912345678912345678'.split(''),
));
i think it is easier to loop thru it twice like this
function checkNumbers(randomArray, guessArray) {
var clone = randomArray.slice(0);
var good = 0;
var regular = 0;
var bad = 0;
var visited = [];
guessArray.forEach(function(guess, index) {
if (guess === clone[index]) { // the guess is in right position
good++;
clone[index] = "x"; // strike it out so it cannot be used later
visited.push(index);
} else if (clone.indexOf(guess) === -1) {
bad++;
visited.push(index);
}
});
guessArray.forEach(function(guess, index) {
if (!visited.includes(index)) {
var match = clone.indexOf(guess);
if (match !== -1) {
regular++;
clone[match] = "x"; // strike it out so it cannot be used later
}
}
});
return {
good: good,
bad: bad,
regular: regular
}
}
first loop is to check the good and bad. and strikeout the value it is good so it cannot be used again.
second loop to check for the regular and strikeout the value it is used so it cannot be used again.
This should work.
function guessNumber (numUser, numRandom) {
if (typeof numUser == 'number') {
numUser = numUser.toString().split('');
}
if (typeof numRandom == 'number') {
numRandom = numRandom.toString().split('');
}
if (typeof numRandom != 'object' || typeof numUser != 'object') {
return false;
}
if (numRandom == numUser) {
return true;
}
var numRegular = {},
numBuenos = {},
numMalos = {},
numRepeat = {};
for(var i = 0; i < numRandom.length; i++) {
if (!numRepeat[numRandom[i]]) {
numRepeat[numRandom[i]] = 0;
}
numRegular[numRandom[i]] = 0;
numRepeat[numRandom[i]]++;
}
for (var i = 0; i < numUser.length; i++) {
if (numUser[i] == numRandom[i]) {
numBuenos[numUser[i]] = numUser[i];
}else if ($.inArray(numUser[i], numRandom)) {
if (!numRegular[numUser[i]]) {
numRegular[numUser[i]] = 0;
}
if (numRegular[numUser[i]] < numRepeat[numUser[i]]) {
numRegular[numUser[i]]++;
} else {
numMalos[numUser[i]] = numUser[i];
}
} else {
numMalos[numUser[i]] = numUser[i];
}
}
return {
regular: Object.values(numRegular).reduce((a, b) => a + b),
buenos: Object.keys(numBuenos).length,
malos: Object.keys(numMalos).length
};
}
console.log(guessNumber(8365, 8512));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

loop through 'distinct' values and ignore duplicates - javascript

I'm completely rewriting this question to explain it better,
i have a list of objects as shown in the image.
These all have the property statusCode: 62467 but the journey property goes like: 0,1,2,3,3,4,4,4,4
i want to loop through these objects and return the FIRST of the duplicated objects with the same journey number.
So i want to return the bold objects: 0,1,2,3,3,4,4,4,4
$.each(points, function (index, point) {
for (i = 0; i < journeyNumber.length; i++) {
if (point.k.journey === journeyNumber[i] && point.k.statusCode === '62467') {
console.log(point);
latlngs.push(point.j.aa.k);
latlngs.push(point.j.aa.B);
}
}
});
the screenshot is the log of console.log(point), so ideally i would like another loop inside which returns only the first object of the same journey number.
hope this makes sense and thank you for your time.
You can track which numbers have already been dealt with, and, on finding duplicates of them, skip them.
var already_seen = []; //container for logging unique values
$.each(points, function(index, point) {
if (already_seen.indexOf(point) !== -1) return; //if already in container, skip
already_seen.push(point); //log unseen values in the container
for (i = 0; i < journeyNumber.length; i++) {
if (journey === journeyNumber[i] && statusCode === '62467') {
latlngs.push(lat);
latlngs.push(lng);
console.log(journey)
}
}
});
How about making use of filter
var unique = [];
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
$.each(points, function(index, point) {
for (i = 0; i < journeyNumber.length; i++) {
if (journey === journeyNumber[i] && statusCode === '62467') {
latlngs.push(lat);
latlngs.push(lng);
unique.push(journey)
}
}
console.log(unique.filter(onlyUnique));
});

Javascript TypeError: Array is undefined

to test some things in javascript I am building a small minesweeper.
The following code is the initialization of the two-dimension array P.field. Afterwards a number of random fields are getting filled with an x, symbolizing that there's a mine on this field.
P.field = new Array(num);
for (var i = 0; i < P.field.length; i++)
P.field[i] = new Array(num);
$.each(P.field, function(index, key) {
$.each(key, function(i, k) {
P.field[index][i] = '-';
});
});
var arr = [];
while (arr.length < 10) {
var found = false;
var randomnumber = Math.ceil(Math.random()*(num*num-1));
for (var i = 0; i < arr.length; i++)
if (arr[i] == randomnumber) { found = true; break; }
if (!found) arr[arr.length] = randomnumber;
}
for (var i = 0; i < arr.length; i++) {
P.field[ Math.floor(arr[i]/num) ][ Math.floor(arr[i]-Math.floor(arr[i]/num)*num)-1 ] = 'x';
}
However, in my algorithm for counting the mines in surrounding fields, I get the console error TypeError: P.field[(r+1)] is undefined. Every field (except of those from the last row) returns this error, which is something I can't quite understand.
P.field[rows][columns] has a length of 10 per dimension in my tests ([10][10]). When I try to get the value of P.field[9][0] to P.field[9][9] there's nothing wrong. However when I adress any smaller row, this exception kicks in (P.field[0 + 1][0], P.field[3 + 1][6], and what so ever)...
I hope someone can tell me why.
edit
More code:
onReady: function() {
$('#sweeper table').on('click', 'td', function(e) {
var row = $(this).parent().attr('class'); // Class represents the index of the array
var column = $(this).attr('class'); // Class represents the index of the array
P.openField(row, column, $(this));
});
},
openField: function(r, c, e) {
if ( P.field[r][c] == 'x' ) {
e.addClass('mine');
} else {
e.html( P.surroundingMineCount(r, c) );
e.addClass('opened');
}
},
surroundingMineCount: function(r, c) {
var count = 0;
if ( P.field[r][c-1] == 'x' ) count++;
if ( P.field[r-1][c-1] == 'x' ) count++;
if ( P.field[r][c+1] == 'x' ) count++;
if ( P.field[r-1][c] == 'x' ) count++;
if ( P.field[r-1][c+1] == 'x' ) count++;
if ( P.field[r+1][c] == 'x' ) count++;
if ( P.field[r+1][c-1] == 'x' ) count++;
return count;
},
Right now I have no validation if the r+1 or r-1 is actually a valid index for that array (I had one in, but removed it for testing). However that can't really be the error, because I even get errors in the middle of the table.
Looking at the code you've provided versus the errors you've had thrown, I'm skeptical about your suspected cause as the code used does indeed generate the correct set of arrays.
I suspect it may be a slightly simpler issue, the example generation code you've provided uses:
P.field = new Array(num);
which has P as a capital, whereas the error that you've had thrown uses it as lowercase:
TypeError: p.field[(r+1)] is undefined
Are you sure you haven't accidentally just used the incorrect case when testing?

Javascript Function to split and return a value from a string

I am trying to grab a certain value. I am new to javascript and I can't figure out why this is not working.
If I parse "kid_2" I should get "kostas". Instead of "Kostas" I always get "02-23-2000". So I must have a logic problem in the loop but I am really stuck.
function getold_val(fieldname,str){
var chunks=str.split("||");
var allchunks = chunks.length-1;
for(k=0;k<allchunks;k++){
var n=str.indexOf(fieldname);
alert(chunks[k]);
if(n>0){
var chunkd=chunks[k].split("::");
alert(chunkd);
return chunkd[1];
}
}
}
var test = getold_val('kid_2','date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||');
alert(test);
A regex may be a little more appealing. Here's a fiddle:
function getValue(source, key){
return (new RegExp("(^|\\|)" + key + "::([^$\\|]+)", "i").exec(source) || {})[2];
}
getValue("date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||","kid_2");
But if you want something a little more involved, you can parse that string into a dictionary like so (fiddle):
function splitToDictionary(val, fieldDelimiter, valueDelimiter){
var dict = {},
fields = val.split(fieldDelimiter),
kvp;
for (var i = 0; i < fields.length; i++) {
if (fields[i] !== "") {
kvp = fields[i].split(valueDelimiter);
dict[kvp[0]] = kvp[1];
}
}
return dict;
}
var dict = splitToDictionary("date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||","||","::");
console.log(dict["date_1"]);
console.log(dict["date_2"]);
console.log(dict["kid_1"]);
console.log(dict["kid_2"]);​
This works, here's my fiddle.
function getold_val(fieldname,str) {
var chunks = str.split('||');
for(var i = 0; i < chunks.length-1; i++) {
if(chunks[i].indexOf(fieldname) >= 0) {
return(chunks[i].substring(fieldname.length+2));
}
}
}
alert(getold_val('kid_2', 'date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||'));
The issue with your code was (as #slebetman noticed as well) the fact that a string index can be 0 because it starts exactly in the first letter.
The code is almost the same as yours, I just didn't use the second .split('::') because I felt a .substring(...) would be easier.
There are two bugs. The first error is in the indexOf call:
var n = str.indexOf(fieldname);
This will always return a value greater than or equal to 0 since the field exists in the string. What you should be doing is:
var n = chunks[k].indexOf(fieldname);
The second error is in your if statement. It should be:
if(n >= 0) {
...
}
or
if(n > -1) {
...
}
The substring you are looking for could very well be the at the beginning of the string, in which case its index is 0. indexOf returns -1 if it cannot find what you're looking for.
That being said, here's a better way to do what you're trying to do:
function getold_val(fieldName, str) {
var keyValuePairs = str.split("||");
var returnValue = null;
if(/||$/.match(str)) {
keyValuePairs = keyValuePairs.slice(0, keyValuePairs.length - 1);
}
var found = false;
var i = 0;
while(i < keyValuePairs.length && !found) {
var keyValuePair = keyValuePairs[i].split("::");
var key = keyValuePair[0];
var value = keyValuePair[1];
if(fieldName === key) {
returnValue = value;
found = true;
}
i++;
}
return returnValue;
}

Number expected error on sort

Other browsers work fine but in IE i get Number Expected when using the following code and it runs into a null object on the sort function.
http://jsfiddle.net/R3ndd/2/
function list_response(jsonData) {
"use strict";
var lists = document.getElementById("lists"), anchors = document.getElementById("anchors"), jItems = jsonData.items;
var results = [], anks = [], vList, pListName, item, videoItem;
var i, j, jLen, iLen = jItems.length;
for (var i = 0; i < iLen; i++) {
if(jItems[i] != null ){
jItems[i].nameLower = jItems[i].name.toLowerCase();
}
}
jItems.sort(function (a, b) {
if(a != null && b != null){
return a.nameLower.localeCompare(b.nameLower);
}
});
Any suggestions? Thanks!
My Solution
I decided to remove the null object (which works) from json using the following:
var y;
for (var x in jItems) {
if ( Object.prototype.hasOwnProperty.call(jItems,x)) {
y = jItems[x];
if (y==="null" || y===null || y==="" || typeof y === "undefined") {
delete jItems[x];
}
}
}
Don't know why IE does that, but it is it's habit to trouble us good people :). Well, I think this will be better way.
/* NOT NEEDED.
for (var i = 0; i < iLen; i++) {
if(jItems[i] != null ){
jItems[i].nameLower = jItems[i].name.toLowerCase();
}
}*/
jItems.sort(function (a, b) {
return a && b ? a.toLowerCase().localeCompare(b.toLowerCase()) : 0;
});
UPDATE:
Well, I think I know where IE is troubling. Sorry MS, this time IE hasn't any fault. What happened was that in case where either a or b were null/''/false (or any falsy value), your callback didn't return any value. That explians the 'Number expected' error. But I took care of that, so my answer will probably work. :)

Categories

Resources