How to get correct array Length in JQuery - javascript

I don't know why I getting 2020 array length what process I am missing Please run this code into browser and see result,please give me feedback which I am missing.
var offline_rijksmuseum_child_barcodes_array = new Array();
var offline_rijksmuseum_child_barcodes_new = new Array();
var news = '[{"2018":["testeer","testeer2","testeer3"],"2019":["sd","sd2","sd3"]},{"2018":["dfg"],"2019":["praafd"]}]';
var obj = $.parseJSON(news);
var i = 0;
$.each(obj, function (i, objectData) {
i++;
if(i == 1) {
$.each(objectData, function (key, obj_new) {
if(key == '2018') {
offline_rijksmuseum_child_barcodes_array[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_array);
}
if(key == '2019') {
offline_rijksmuseum_child_barcodes_array[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_array);
}
});
}
else if(i == 2) {
$.each(objectData, function (key, obj_new) {
if(key == '2018') {
offline_rijksmuseum_child_barcodes_new[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_new);
}
if(key == '2019') {
offline_rijksmuseum_child_barcodes_new[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_new);
}
});
}
});
console.log(offline_rijksmuseum_child_barcodes_array.length, offline_rijksmuseum_child_barcodes_array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Arrays make sense for ordered lists of data (which should not have blank spots, such as with sparse arrays). Your offline_rijksmuseum_child_barcodes_array is a spare array - you're assigning to an index when [index - 1] does not exist in the array - which results in a very odd structure - 2017 <empty> elements followed by two actual elements. You might consider using an object instead of an array:
var offline_rijksmuseum_child_barcodes_array = {};
var offline_rijksmuseum_child_barcodes_new = {};
To get the "length" of the resulting object, you can check the length of its keys:
Object.keys(offline_rijksmuseum_child_barcodes_array).length
That way, lines like
offline_rijksmuseum_child_barcodes_array[key] = obj_new;
will only result in associating the property name [key] with the value obj_new, without also causing spare-array weirdness (like the making the .length of the collection huge in the process).
// var x = ['vdf','dsgfdsfds','dsgfdfgdsfds'];
// console.log(x);
var offline_rijksmuseum_child_barcodes_array = {};
var offline_rijksmuseum_child_barcodes_new = {};
var news = '[{"2018":["testeer","testeer2","testeer3"],"2019":["sd","sd2","sd3"]},{"2018":["dfg"],"2019":["praafd"]}]';
var obj = $.parseJSON(news);
var i = 0;
$.each(obj, function(i, objectData) {
i++;
if (i == 1) {
$.each(objectData, function(key, obj_new) {
if (key == '2018') {
offline_rijksmuseum_child_barcodes_array[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_array);
}
if (key == '2019') {
offline_rijksmuseum_child_barcodes_array[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_array);
}
});
} else if (i == 2) {
$.each(objectData, function(key, obj_new) {
if (key == '2018') {
offline_rijksmuseum_child_barcodes_new[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_new);
}
if (key == '2019') {
offline_rijksmuseum_child_barcodes_new[key] = obj_new;
//console.log(offline_rijksmuseum_child_barcodes_new);
}
});
}
});
console.log(offline_rijksmuseum_child_barcodes_array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

would suggest to construct a new obj like tmpObj and push key & value and then push tmpObj into array. and you will get the array lenght also.
temp object construction
var tmpObj = {};
tmpObj[key] = tmpObj[key] || [];
tmpObj[key].push(obj_new);
try below code snippet.
var offline_rijksmuseum_child_barcodes_array = new Array();
var offline_rijksmuseum_child_barcodes_new = new Array();
var news = '[{"2018":["testeer","testeer2","testeer3"],"2019":["sd","sd2","sd3"]},{"2018":["dfg"],"2019":["praafd"]}]';
var obj = $.parseJSON(news);
var i = 0;
$.each(obj, function (i, objectData) {
i++;
if(i == 1) {
$.each(objectData, function (key, obj_new) {
var tmpObj = {};
if(key == '2018') {
tmpObj[key] = tmpObj[key] || [];
tmpObj[key].push(obj_new);
offline_rijksmuseum_child_barcodes_array.push(tmpObj );
}
if(key == '2019') {
tmpObj[key] = tmpObj[key] || [];
tmpObj[key].push(obj_new);
offline_rijksmuseum_child_barcodes_array.push(tmpObj);
}
});
}
else if(i == 2) {
$.each(objectData, function (key, obj_new) {
var tmpObj = {};
if(key == '2018') {
tmpObj[key] = tmpObj[key] || [];
tmpObj[key].push(obj_new);
offline_rijksmuseum_child_barcodes_new.push(tmpObj);
}
if(key == '2019') {
tmpObj[key] = tmpObj[key] || [];
tmpObj[key].push(obj_new);
offline_rijksmuseum_child_barcodes_new.push(tmpObj);
}
});
}
});
console.log(offline_rijksmuseum_child_barcodes_array.length, '---', offline_rijksmuseum_child_barcodes_array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

Last Key in JavaScript array appearing as Length?

Bit of a weird one. Am using the following code build an array from a json object to make it easier to reference later in the code. However it would appear that when the last item of each array is created, rather than adding a new item, the Key of the item appears as the length of the array.
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
for (var perf_no in obj.Extras) {
if (extras[perf_no] == undefined) {
var arr = new Array();
for (var extra in obj.Extras[perf_no]) {
if (arr[extra] == undefined) {
arr[extra] = obj.Extras[perf_no][extra];
}
}
extras[perf_no] = arr;
}
}
break;
}
}
}
The resulting array appears as below:
Any ideas what's going on here?
Edit:
Sample of Json below
{"Extras":{"32516":{"24186":"Example text"},"32515":{"24186":"Example text"},"32514":{"24186":"Example text"},"32512":{"24186":"Example text"},"32513":{"24186":"Example text"},"32511":{"24186":"Example text"},"32510":{"24186":"Example text"},"32509":{"24186":"Example text"},"32507":{"24186":"Example text"},"32503":{"24186":"Example text"},"32506":{"24186":"Example text"},"32505":{"24186":"Example text"},"32508":{"24186":"Example text"},"32502":{},"32497":{}}}
What's going on hear is that you are using for..in to iterate over an array, which is a no-no because it iterates properties that are not the array elements (such as the .length property). Instead, use Array#forEach:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
obj.Extras.forEach(function (item, idx) {
if (typeof extras[idx] === 'undefined') {
var arr = new Array();
item.forEach(function (item2, idx2) {
if (typeof arr[idx2] === 'undefined') {
arr[idx2] = item2;
}
});
extras[idx] = arr;
}
});
break;
}
}
}
The innermost loop is pretty pointless and can be replaced with Array#slice:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null) {
if (obj.Extras != null) {
obj.Extras.forEach(function (item, idx) {
if (typeof extras[idx] === 'undefined') {
extras[idx] = item.slice();
}
});
break;
}
}
}
The next inner loop can be replaced with Array#map and two if statements can be combined:
perfsJson = $.parseJSON(result);
var extras = new Array();
for (var i = perfsJson.length - 1; i >= 0; i--) {
var obj = perfsJson[i];
if (obj != null&& obj.Extras != null) {
extras = obj.Extras.map(function (item) {
return item.slice();
});
break;
}
}
In fact, most of this code can be simplified:
function findLastElement(arr) {
for (var i = arr.length - 1; i >= 0; i -= 1) {
if (arr[i] != null && arr[i].Extras != null) { return arr[i]; }
}
}
perfsJson = $.parseJSON(result);
var lastElement = findLastElement(perfsJson);
var extras = lastElement
? lastElement.Extras.map(function (item) { return item.slice(); })
: [];

Push to an array in a nested loop is repeating the last value

I am trying to push elements to an array in a nested loop, but only the last item is getting repeated in the final array, where am I going wrong, very new to javascript asynchronous concept.Below is the function in which I push the items to an array.
$scope.showBeList = function(feed) {
if (feed[srcServ.KEY_CONTENT_TEXT]) {
var content = JSON.parse(feed[srcServ.KEY_CONTENT_TEXT])
if (content) {
$scope.beList = {};
for (var key in content) {
var decorationVal;
//reading value from a lokijs collection
var decoration = dataServ[srcServ.CONST_COLLECTION_DECORATION].find({
'name': key
});
if (decoration && decoration.length) {
decorationVal = decoration[0];
if (decorationVal != null) {
var tempObj = JSON.parse(decorationVal.value);
if (tempObj) {
var header = tempObj[key][key + '_HEADER'];
if (header) {
var counter = content[key].length;
var tempItems = [];
for (var j = 0; j < content[key].length; j++) {
(function(j) {
var obj = {};
obj[srcServ.KEY_MAIN_HEADER] = tempObj[key][srcServ.KEY_DESC];
obj[srcServ.KEY_SUB_HEADER] = header[srcServ.KEY_DESC];
obj.id = j;
var itemVal = content[key][j][key + '_HEADER'];
var details = [];
var notes = [];
for (var item in itemVal) {
var val = null;
var found = false;
for (var i = 0; i < header.field.length; i++) {
if (header.field[i].name == item) {
val = header.field[i];
found = true;
break;
}
}
if (found && val != null) {
val[srcServ.KEY_DESC_VALUE] = itemVal[item];
details.push(val);
}
}
obj.details = details;
counter--;
if (counter == 0) {
$scope.showMoreDetails = true;
$scope.beList.beItems = tempItems;
console.log(JSON.stringify($scope.beList));
}
tempItems.push(obj)
})(j);
// $scope.beList.beItems.push(obj);
}
}
}
}
}
}
}
}
}

checking individual element of an array by calling a method

Can i optimize my code bit more to reduce number of line?
I am checking/passing individual array elements? Can i make it re-write in a generic way?
for (var i = 0; i < $scope.studentReport.Students.length; i++)
{
if (_isValueNan($$scope.studentReport.Students[i].Age))
$$scope.studentReport.Students[i].Age = null;
if (_isValueNan($$scope.studentReport.Students[i].Number))
$$scope.studentReport.Students[i].Number = null;
if (_isValueNan($$scope.studentReport.Students[i].Height))
$$scope.studentReport.Students[i].Height = null;
}
var _isValueNan = function (item) {
var result = false;
if (typeof item == 'number' && isNaN(item))
result = true;
return result;
}
With ref to Stumblor's answer:
for (var i = 0; i < $scope.studentReport.Students.length; i++) {
_checkValueNan($$scope.studentReport.Students[i], ["Age", "Number", "Height"]);
}
var _checkValueNan = function (item, values) {
values.forEach(function (val) {
if (typeof item[val] === 'number' && isNaN(item[val])) item[val] = null;
});
}
You can nullify the property internally in the function, and also pass the item and property value in independently. For example:
for (var i = 0; i < $scope.studentReport.Students.length; i++)
{
_checkValueNan($$scope.studentReport.Students[i], "Age");
_checkValueNan($$scope.studentReport.Students[i], "Number");
_checkValueNan($$scope.studentReport.Students[i], "Height");
}
var _checkValueNan = function (item, valueName) {
if (typeof item[valueName] == 'number' && isNaN(item[valueName]))
item[valueName] = null;
}
EDIT:
Leading on from Vicky Gonsalves answer, you could additionally check ANY of the properties of the object, which might be a more scalable solution.
var _checkAllValueNan = function (item) {
for(var key in item) { // iterates all item properties
if (!item.hasOwnProperty(key)) continue; // ensures not prop of prototype
if (typeof item[key] == 'number' && isNaN(item[key])) item[key] = null;
}
}
for (var i = 0; i < $scope.studentReport.Students.length; i++)
{
_checkAllValueNan($scope.studentReport.Students[i]);
}

Taking more time to fetch records in json object using javascript function

I have 20000 records, below javascript function taking more time to fetch records in Json object.
$("#txtKey").keyup(function() {
var value = $("#txtKey").val();
var exactMatch = $('#exactMatch').is(':checked');
var key = $("#SearchKey option:selected").val();
var filteredData = vLookup(value, data, key, exactMatch);
fillTableDataDynamic(filteredData);
});
function vLookup(value, data, key, exactMatch) {
if (typeof data === "object" && !(data instanceof Array)) {
var arrData = [];
arrData.push(data);
data = arrData;
}
var filteredData = [];
var transValue = value.toLowerCase();
for (var i = 0; i < data.length; i++) {
if (exactMatch) {
if (JSON.stringify(data[i][key]).indexOf(value) > -1) {
filteredData.push(data[i]);
}
} else {
if (JSON.stringify(data[i][key]).toLowerCase().indexOf(transValue) > -1) {
filteredData.push(data[i]);
}
}
}
return filteredData;
}
Any alternate way to fetch record?
Thanks Advance.
from the look of your data
if (exactMatch) {
if (data[i][key].toString().indexOf(value) > -1) {
filteredData.push(data[i]);
}
} else {
if (data[i][key].toString().toLowerCase().indexOf(transValue) > -1) {
filteredData.push(data[i]);
}
}
will work for you
so - no speed difference
try this: uses Array.prototype.filter - there's extra overhead in the function call, but the filter function may yet achieve speed improvement
function vLookup(value, data, key, exactMatch) {
if (typeof data === "object" && !(data instanceof Array)) {
var arrData = [];
arrData.push(data);
data = arrData;
}
var transValue = value.toLowerCase();
if (exactMatch) {
return data.filter(function(datum) {
return datum[key].toString().indexOf(value) > 1;
});
} else {
return data.filter(function(datum) {
return datum[key].toString().indexOf(transValue) > 1;
});
}
}

How to create a multi dimensional object or array in javascript or jquery

I want to store the data in to multidimensional arrays or object and send the data to the controller. I have defined the object in javascript like
var dynamicprofile = new Object();
var certidarry = [];
var trueorfalse = [];
dynamicprofile.profilename = "certifications";
$(".certclass").each(function (index, element) {
certidarry.push(i);
if (element.checked == false) {
trueorfalse.push(false);
}
else if (element.checked == true) {
trueorfalse.push(true);
}
});
dynamicprofile.idarray = certidarry;
dynamicprofile.trueorfalse = trueorfalse;
dynamicprofile.profilename = "projects";
var projectidarry12 = [];
var trueorfalsearry12 = [];
$(".Projectsclass").each(function (index, element) {
projectidarry12.push(index);
if (element.checked == false) {
trueorfalsearry12.push(false);
}
else if (element.checked == true) {
trueorfalsearry12.push(true);
}
});
dynamicprofile.idarray = projectidarry12;
dynamicprofile.trueorfalse = trueorfalsearry12;
If the see the json content then it is displaying only the latest information. but it is not showing the content that is saved earlier. how can i save the content.
The problem is that you are overriding: dynamicprofile.profilename, dynamicprofile.idarray and dynamicprofile.trueorfalse.
Maybe you can try one of these solutions among others:
1.
var dynamicprofile = new Object();
var certidarry = [];
var trueorfalse = [];
dynamicprofile['certifications'] = {};
$(".certclass").each(function (index, element) {
certidarry.push(index);
if (element.checked == false) {
trueorfalse.push(false);
}
else if (element.checked == true) {
trueorfalse.push(true);
}
});
dynamicprofile['certifications'].idarray = certidarry;
dynamicprofile['certifications'].trueorfalse = trueorfalse;
dynamicprofile['projects'] = {};
var projectidarry12 = [];
var trueorfalsearry12 = [];
$(".Projectsclass").each(function (index, element) {
projectidarry12.push(index);
if (element.checked == false) {
trueorfalsearry12.push(false);
}
else if (element.checked == true) {
trueorfalsearry12.push(true);
}
});
dynamicprofile['projects'].idarray = projectidarry12;
dynamicprofile['projects'].trueorfalse = trueorfalsearry12;
--
2.
var dynamicprofile = [];
var certidarry = [];
var trueorfalse = [];
$(".certclass").each(function (index, element) {
certidarry.push(index);
if (element.checked == false) {
trueorfalse.push(false);
}
else if (element.checked == true) {
trueorfalse.push(true);
}
});
dynamicprofile.push({
profilename: "certifications",
idarray: certidarry,
trueorfalse: trueorfalse
});
var projectidarry12 = [];
var trueorfalsearry12 = [];
$(".Projectsclass").each(function (index, element) {
projectidarry12.push(index);
if (element.checked == false) {
trueorfalsearry12.push(false);
}
else if (element.checked == true) {
trueorfalsearry12.push(true);
}
});
dynamicprofile.push({
profilename: "projects",
idarray: projectidarry12,
trueorfalse: trueorfalsearry12
});
u can do it in following way
var a=new Array();
for(vr i=0;i<10;i++)
{
a[i]=new Array();
a[i][0]='value1';
a[i][1]='value2';
}

Categories