Error while executing mapreduce in mongo-shell - javascript

The following error occours
Thu May 23 07:14:53.437 JavaScript execution failed: map reduce failed:{
"errmsg" : "exception: JavaScript execution failed: TypeError: Cannot read property 'product_category' of undefined near '(values[i].product_category)' (line 21)",
"code" : 16722,
"ok" : 0
at src/mongo/shell/collection.js:L970
My map and reduce function are:
map1 = function()
{
emit({Product_id:this.Product_id
},
{
product_category:this.product_category
});
}
reduce1 = function(key, values)
{
var ref = new Array();
var count = 0;
var tmp="";
var pdt_array = new Array();
for (var i = 1; i <= values.length; i++) {
if( i == 1 )
{
pdt_array_array[i] = values[i];
}
else
{
tmp = values[i];
while(i > 1)
{
if(tmp == pdt_array[i])
{
ref.push(values[i].product_category);
count++;
}
i--;
}
pdt_array[i] = tmp;
tmp = "";
}
}
return {product_category:ref, Count:count}
}
db.DummyReverse.mapReduce(map1, reduce1, {out:{reduce:"product_count_while"}})

The issue is that you are not returning the same format from reduce function as you are emitting as value. Since reduce function can be called 0, once or multiple times for each key you must use the exact same format in all of those cases and you cannot assume that your reduce function will be called only once.

Javascript arrays are 0-indexed. So your last for-run want to access a array index, which doesn't exist. I hope I interpret your code right.
[...]
for (var i = 0; i < values.length; i++) {
if ( i == 0) {
pdt_array_array[i] = values[i];
} else {
tmp = values[i];
while(i > 0) {
if(tmp == pdt_array[i]) {
ref.push(values[i].product_category);
count++;
}
i--;
}
pdt_array[i] = tmp;
tmp = "";
}
}
[...]
Take notice at for (var i = 0; i < values.length; i++). So the n-th element has the index n-1. The last element length-1.
Remarks: Are you sure you get no infinite loop with the for-loop increasing i and in the while decreasing it?

Related

The function prints the days of the week(week.name) which have the highest traffic(week.traffic). Can you give me an alternate logic

in the function below an array of objects is passed to the function. The object has 2 attributes: name and traffic. I am writing those days of week which have highest traffic to the console.
function mostPopularDays(week) {
var Days = [];
if (week == null || week.length == 0) {
return null;
}
var max = week[0].traffic;
var j;
var k[];
for (i = 1; i < week.length; i++) {
if (week[i].traffic > max) {
max = week[i].traffic;
j = i;
} else if (week[i].traffic == max) {
j = i;
k.push(i);
}
}
if (j != k[k.length - 1]) {
Days.push(week[j].name)
console.log(Days[0]);
} else {
for (i = 0; i < k.length; k++) {
Days.push(week[(k[i])].name);
cosole.log(Days[i]);
}
Days[k.length] = week[j].name;
console.log(Days[k.length]);
}
}
Argument passed to the function is an array of objects. I am comparing values based on objects.traffic and printing those object.names which have highest traffic.
You may simply reduce it:
const mostPopularWeekDays = week => {
let max = 0; //a helper variable to store the current maximum
return week.reduce((res, {name, traffic}) => {
if(traffic > max){ //looks like our maximum gets toped
max = traffic; //so set that new maximum
return [name]; //and keep on going with today
}
if(traffic === max) res.push(name); //we dont have a new maximum but its high enough to count as a maxum so add it
return res;
}, []);
}
console.log(mostPopularWeekDays([
{name:"Mo", traffic:10},
{name:"Tu", traffic:15},
{name:"We", traffic:10},
{name:"Th", traffic:10},
{name:"Fr", traffic:10},
{name:"St", traffic:15},
{name:"Su", traffic:10}
]));

why does it returns '-1' instead of the index of the index jQuery

I'm running a 'for' loop to check if the elements in the winOptions array are in the oneNums array. However, every time I use indexOf property it sends back -1 even if the number is in the oneNums array. Is it possible it returns that because ['1','2'] is different that [1,2]? How can I fix this.
I have this variables:
var oneNums = [];
var winOptions = [[1,2,3],[4,5,6],[7,8,9],[1,5,9],[3,5,9],[1,4,7],[2,5,8],[3,6,9]];
var a;
And this jQuery function:
$('.btn-xo').click(function(){
if (turn === 'one'){
$(this).text(pickOne);
$(this).prop('disabled', true);
oneNums.push($(this).val());
oneNums.sort(function(a, b){
return a - b;
});
for(var i = 0; i < winOptions.length; i++){
for(var j = 0; j < winOptions[i].length; j++){
a = oneNums.indexOf(winOptions[i][j]);
if (a === -1){
p1 = [];
break;
} else {
p1.push(oneNums[a]);
console.log('aca');
}
}
}
console.log(a);
turn = 'two';
count += 1;
}
indexOf string with number will fail. So, change number to string
First convert number to String, using .toString()
for(var i = 0; i < winOptions.length; i++){
for(var j = 0; j < winOptions[i].length; j++){
a = oneNums.indexOf((winOptions[i][j]).toString());
if (a === -1){
p1 = [];
break;
} else {
p1.push(oneNums[a]);
console.log('aca');
}
}
}
Check these two examples,
['1','2'].indexOf(1); o/p ===> -1
['1','2'].indexOf((1).toString()); o/p ===> 0

Can anyone explain why I am getting this error in Javascript? [Cannot read property 'length' of undefined]

Here is my code:
function isEven(num) {;
if (num % 2 === 0) {
return true;}
else {
return false;}
}
function convertToIntegers(lst) {
lst.split(' ');
var len = lst.length;
var count = 0;
while (count < len) {
lst[count] = parseInt(lst[count]);
count++}
}
function iqTest(numbers){
var int_list = convertToIntegers(numbers);
var e_list = [];
var o_list = [];
var count = 0;
var len_int = int_list.length;
while (count < len_int) {
if (isEven(int_list[count]) === true) {
e_list.push(count);}
else if (isEven(count) === false) {
o_list.push(count);}
count++}
if (e_list.length < 2 && e_list.length > 0 && o_list.length > 2) {
return e_list[0];}
else if (o_list.length < 2 && o_list.length > 0 && e_list.length > 2) {
return o_list[0];}
}
Everytime I run it I get this error that says "TypeError: Cannot read property 'length' of undefined at iqTest". Can anyone explain to me how I can fix this error. I don't understand why any object would be undefined in my code. Every var declaration I make is complete. I thought undefined only came up if I wrote something like 'var a' without defining it.
Tomer W and Patrick Evans are right. change your helper function
function convertToIntegers(lst) {
lst = lst.split(' ');
var len = lst.length;
var count = 0;
while (count < len) {
lst[count] = parseInt(lst[count]);
count++;
}
return lst;
}
this way you are storing th result of the split and then returning the array when done.
that being said this function isn't needed. Check out the built in array function map
this one is very easy!
in these situations you want to trace the value back.
you use .length in iqTest() in the line var len_int = int_list.length;
the last assignment to int_list is at line var int_list = convertToIntegers(numbers);
glimps at convertToIntegers(numbers) shows no return statement.
therefore conclusion:
convert2Integers() returns nothing into int_list
then you use int_list.length; of undefined
it seems you wish to return lst from convert2Integers()
function convertToIntegers(lst) {
lst = lst.split(' '); // NOTICE CHANGE, + create a different list!
var len = lst.length;
var count = 0;
while (count < len) {
lst[count] = parseInt(lst[count]);
count++
}
return lst; //THIS LINE was Missing!
}
To expand on #Patrick Evans comment you need to save the result of the split then use that for your while loop. Just as a side note you know the number of iterations of the loop so you can use a for loop.
function convertToIntegers(lst) {
//lst.split(' ');
var lst_array = lst.split(' ');
var len = lst_array .length;
var count = 0;
while (count < len) {
lst_array[count] = parseInt(lst_array[count]);
count++}
}
//
//for loop code
//
//for(i=0;i<lst_array.length;i++){
// lst_arry[i] = parseInt(lst_array[i]);
//}

checking multiple elements in javascript array

I have an array 'type' with multiple elements.how to check two elements contains in 'type' array?
i have tried the below code
var i, j;
var type = [];
for (i = 1; i <= count; i++)
{
var filetype_value = parseInt((document.submission['select_type_' + i].value));
type.push(filetype_value);
}
function search(arg)
{
for (j = 1; j <= count; j++)
{
if (type[j] === arg)
{
return true;
}
else
{
return false;
}
}
}
if(search(1) && search(2))
{
alert("Contains in array")
}
There is some problems with your approach.
1) You are just checking if type[1]===arg it will return true otherwise it will return false. So it will just check for type[1].
2) because file_type value is string so filetype_value' === arg is never going to be true.
3) In your loop j=1 will never check for first element of array.
Try this
function search(arg){
var matched = false;
for (j = 0; j <= type.length; j++){
if (type[j] == arg){
matched = true;
break;
}
}
return matched;
}
You have 2 problems
You are pushing the string "filetype_value" onto your array and not the actual value so in your search function you are actually testing: 'filetype_value' === arg
You are starting your loop using 1, array's start at an index of 0
change
type.push('filetype_value');
to
type.push(filetype_value);
change
for (j = 1; j <= count; j++)
to
for (j = 0; j <= count; j++)
Also instead of doing a loop you can use the array indexOf method to test if a value is in the array
function search(arg){
return type.indexOf(arg) !== -1;
}

find missing range from array of ranges

I am having array of my class that having Minvalue and Maxvalue property.
Suppose in my array i am having three elements
First MinValue=0 and MaxValue=25
Second MinValue=26 and MaxValue=50
Third MinValue=75 and MaxValue=100
Minvalue and Maxvalue can be between 0 to 100.
Now I want to find the missing range from above array having three objects.
The missing range in above array is 51 to 75
There can be more than one missing value at that time i want to find the range having min MinValue.
I want to write code in javascript.
Please help me to solve this.
You should try to start something and handle this problem by yourself.
var arr = [{ Min :0, Max:25 } , { Min:26, Max:28}, { Min:35, Max:41}, { Min:48, Max:71}];
var range = [];
for(var i = 0; i <= 100; i++)
{
range.push(true); // first set it as missing...
}
for(var i = 0 ; i < arr.length ; i++)
{
for(var j = arr[i].Min ; j <= arr[i].Max ; j++)
{
range[j] = false; // loop the array and set it to false
}
}
var missingPart = '';
var start = false;
for(var i = 0 ; i < range.length ; i++) // loop the range array and build result
{
if(range[i])
{
if(!start)
{
start = true;
if(missingPart)
{
missingPart+=", ";
}
missingPart += i;
}
}
else
{
if(start)
{
start = false;
missingPart += ("-" + (i-1));
}
}
}
if(start)
{
missingPart += ("-100");
}
document.getElementById("counter").innerHTML = missingPart
Find the jsFiddle result in here : http://jsfiddle.net/gm4HG/2/
Subtract the previous maxValue from the current minValue. The difference should always be 1. Loop through all the values to find the missing range.

Categories