I have to compare two values. Both values came from different loops.
if the value is an exact match, I push the array differently.
As you can see in the code. I cant use an "else" after the "if" function because it will literate till the loop stop. I would have multiple pushes.
If I add the array.push after the loop there will be 2 pushes.
for (var prop in obj) {
var array = []
for (var item in obj[prop]) {
for (var i = 0; i < doctyp88.length; i += 1) {
var doctyp88ID = doctyp88[i]._id;
var doctyp88name = doctyp88[i]._source['88_name'];
if (item == doctyp88ID) {
array.push({
"name": item,
"count": obj[prop][item],
"archivname": doctyp88name,
});
}
}
array.push({
"name": item,
"count": obj[prop][item],
});
}
}
What is the best way to avoid my problem?
for (var prop in obj) {
var array = []
for (var item in obj[prop]) {
const newObj = {
"name": item,
}
for (var i = 0; i < doctyp88.length; i += 1) {
var doctyp88ID = doctyp88[i]._id;
var doctyp88name = doctyp88[i]._source['88_name'];
newObj.count= obj[prop][item],
if (item == doctyp88ID) {
newObj.archivname = doctyp88name
}
}
array.push(newObj);
}
}
If I understood your question correctly you could use break [label]; statement to exit from nested loop and skip more pushes but don't exit outside for like this:
loop_1:
for (var prop in obj) {
var array = []
loop_2:
for (var item in obj[prop]) {
loop_3:
for (var i = 0; i < doctyp88.length; i += 1) {
var doctyp88ID = doctyp88[i]._id;
var doctyp88name = doctyp88[i]._source['88_name'];
if (item == doctyp88ID) {
array.push({
"name": item,
"count": obj[prop][item],
"archivname": doctyp88name,
});
break loop_2;
}
}
array.push({
"name": item,
"count": obj[prop][item],
});
}
}
Related
Say I have an array of objects like so:
[{"taco":"","burrito":"","scone":"","beans":"true"},
{"taco":"true","burrito":"","scone":"true","beans":""},
{"taco":"true","burrito":"","scone":"","beans":""},
{"taco":"true","burrito":"","scone":"","beans":"true"}]
I need to count the occurrence of each element and return in it in an array
[3, 0, 1, 2]
any ideas would be appreciated, thanks!
I have attempted
var a = datasets.reduce(function (item, index) {
if (typeof item[index] == 'undefined') {
item[index] = 1;
} else {
item[index] += 1;
}
return item;
}, {});
could not get anything like that to work so i attempted converting it to json and then removing any key: value pairs with no value then counting remaining ones but have had no success with that either
function tableToJson(table) {
var data = [];
var headers = [];
for (var i=0; i < table[0].rows[0].cells.length; i++) {
headers[i] = table[0].rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
}
for (var i=1; i< table[0].rows.length; i++) {
var tableRow = table[0].rows[i];
var rowData = {};
for (var j=0; j<tableRow.cells.length; j++) {
rowData[ headers[j] ] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
return data
}
function removeEmpty(jsonObj) {
var newObj = Object.getOwnPropertyNames(jsonObj);
for (var i = 0; i < newObj.length; i++) {
var value = newObj[i];
if (jsonObj[value] === null || jsonObj[value] === undefined) {
delete jsonObj[value];
}
}
}
You can try this
You can do it with reduce().
What i have done is first i check is the object property of current element if it is already in output object. If it's present than i check the value of current element property. if it is true than i increment the property of output object by 1.
If the object property of current element is not available in output than i check for the value of current element property. if it is true i assign output object property with value 1. if false i assign output object property with 0.
let obj = [{"taco":"","burrito":"","scone":"","beans":"true"},
{"taco":"true","burrito":"","scone":"true","beans":""},
{"taco":"true","burrito":"","scone":"","beans":""},
{"taco":"true","burrito":"","scone":"","beans":"true"}]
let op = obj.reduce((output,current)=>{
for(let key in current){
if( output[key] ){
if( current[key] ) output[key]+=1;
} else {
if( current[key] ){
output[key] = 1;
} else{
output[key] = 0;
}
}
}
return output;
},{})
console.log(op);
Try this:
var data = [{
taco: "",
burrito: "",
scone: "",
beans: "true"
},
{
taco: "true",
burrito: "",
scone: "true",
beans: ""
},
{
taco: "",
burrito, "true",
scone: "",
beans: "",
}, {
taco: "true",
burrito: "",
scone: "",
beans: "true"
}]
var total = [0, 0, 0, 0];
data.forEach(function(obj) {
if (obj.taco) {
total[0]++;
}
if (burrito) {
total[1]++;
}
if (obj.scone) {
total[2]++;
}
if (obj.beans) {
total[3]++;
}
})
console.log(total)
You can loop through the array and then loop through the keys of each object. Then increment the key of the countObject if it already exists or assign it zero.
This is dynamic. Even if one of the object has an extra key, it will count them. This doesn't expect all the items of array to have the same keys.
var array = [
{"taco":"","burrito":"","scone":"","beans":"true"},
{"taco":"true","burrito":"","scone":"true","beans":""},
{"taco":"true","burrito":"","scone":"","beans":""},
{"taco":"true","burrito":"","scone":"","beans":"true"}
]
var countObject = {};
array.forEach(item => {
Object.keys(item).forEach(key => {
if (item[key] === "true")
countObject[key] = countObject[key] + 1 || 1
else
countObject[key] = countObject[key] || 0
})
})
console.log(countObject); // get the key and count pair
console.log(Object.values(countObject)); // get the counts in an array
I have an existing array of objects :
existingArray = [
{object1: 'object1'},
{object2: 'object2'}
{object3: 'object3'},
]
I receive a new one :
newArray = [
{object2: 'object2'},
{object3: 'object3'},
{object4: 'object4'}
]
I want only to modify the existing one to get the new one as the result (push+splice)
Here is what I have for now (is there a better way ?)
for (var i = 0; i < newArray.length; i++) {
// loop first to push new elements
var responseToTxt = JSON.stringify(newArray[i]);
var newStatement = false;
for(var j = 0; j < existingArray.length; j++){
var statementToTxt = JSON.stringify(existingArray[j]);
if(statementToTxt === responseToTxt && !newStatement){
newStatement = true;
}
}
if(!newStatement){
statements.push(response[i]);
}
}
var statementsToSplice = [];
for (var i = 0; i < existingArray.length; i++) {
// then loop a second time to split elements not anymore on the new array
var statementToTxt = JSON.stringify(existingArray[i]);
var elementPresent = false;
var element = false;
for(var j = 0; j < newArray.length; j++){
var responseToTxt = JSON.stringify(newArray[j]);
if(responseToTxt === statementToTxt && !elementPresent){
elementPresent = true;
} else {
element = i;
}
}
if(!elementPresent){
statementsToSplice.push(element);
}
}
Then I needed to split multiple times in the array :
existingArray = statementsToSplice.reduceRight(function (arr, it) {
arr.splice(it, 1);
return arr;
}, existingArray.sort(function (a, b) { return b - a }));
Here is the example :
https://jsfiddle.net/docmz22b/
So the final output should always be the new array, but only by push or splice the old one.
In this case, the final outpout will be
existingArray = [
{object2: 'object2'},
{object3: 'object3'}
{object4: 'object4'},
]
The new array could contains multiple new elements and/or deleted elements that is currently in the existingArray
Use shift() and push()
existingArray.shift(); //Removes the first element of the array
existingArray.push({'object4' : 'object4'});
Fiddle
I'm almost 100% sure that there is a better way to do it, but at least this works, feel free to comment any suggestions / optimizations.
existingArray = [
{object1: 'object1'},
{object2: 'object2'},
{object3: 'object3'}
];
newArray = [
{object2: 'object2'},
{object3: 'object3'},
{object4: 'object4'}
];
// Loop all the old values, if is not in the new array, remove it
existingArray.forEach(function(item) {
if(!inArray(item, newArray)) {
var idx = indexOfObjectInArray(item, existingArray);
existingArray.splice(idx, 1);
}
});
// Loop all the new values, if is not in the new array, push it
newArray.forEach(function(item) {
if (!inArray(item, existingArray)) {
existingArray.push(item);
}
});
// Auxiliar functions
function inArray(initialValue, array) {
testValue = JSON.stringify(initialValue);
return array.some(function(item) {
return testValue == JSON.stringify(item);
});
}
function indexOfObjectInArray(initialValue, array) {
var result = -1;
testValue = JSON.stringify(initialValue);
array.forEach(function(item, idx) {
if (testValue == JSON.stringify(item)) {
result = idx;
};
});
return result;
}
Maybe this helps. It features Array.prototype.forEach and Array.prototype.some.
Splice unwanted items
Look if object with same property exist
If yes, then assign new object
Else push the object
var existingArray = [
{ object1: 'object1' },
{ object2: 'object2' },
{ object3: 'object3' },
],
newArray = [
{ object2: 'object22' },
{ object3: 'object33' },
{ object4: 'object44' }
];
function update(base, change) {
var changeKeys = change.map(function (a) { return Object.keys(a)[0]; }),
i = 0;
while (i < base.length) {
if (!~changeKeys.indexOf(Object.keys(base[i])[0])) {
base.splice(i, 1);
continue;
}
i++;
}
change.forEach(function (a) {
var aKey = Object.keys(a)[0];
!base.some(function (b, i, bb) {
if (aKey === Object.keys(b)[0]) {
bb[i] = a; // if that does not work, use bb.splice(i, 1, a);
return true;
}
}) && base.push(a);
});
}
update(existingArray, newArray);
document.write('<pre>' + JSON.stringify(existingArray, 0, 4) + '</pre>');
Consider the following json value:
{"Operator":{"DT5241":{"name":"LESLIE, Alec "},"DT3709":{"name":"DAWSON, Peter"},"DT4206":{"name":"PEPWORTH, Jasmine"}
How can I convert this to array?
I have tried doing this: Operator being my arr2[3]
var array = $.map(arr2[3], function(value, index) {
return [value];
});
But it does not help. It gives value as this:
0:Object
DT5241:Object
DT3709:Object
DT4206:Object
I need only array list.
This works.
But its not inserting value to my table:
var dataArray2 = [['TruckName', 'OperatorName']];
for (var i = 3; i < arr2.length; i++) {
for (var j = 0; j < array.length; j++){
dataArray2.push([array[i], array[i].name]);
}
I think the problem is arr2[3] is the object with 1 item that is the object with Operator key, so you need to iterate through arr2[3].Operator
var arr2 = [];
arr2[3] = {
"Operator": {
"DT5241": {
"name": "LESLIE, Alec "
},
"DT3709": {
"name": "DAWSON, Peter"
},
"DT4206": {
"name": "PEPWORTH, Jasmine"
}
}
}
var array = $.map(arr2[3].Operator, function(value, key) {
var obj = {};
obj[key] = value;
return obj;
});
console.log(array)
$('#result').html(JSON.stringify(array))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="result"></div>
I have a JSON array like below:
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
I don't know which keys does exists in this array.
I want to get all the existing key from the array.
It should be possible something like this:
for(i=0;i<jsonArray.lenght;i++){
// something like- key = jsonArray[i].key
// alert(key);
}
Please tell me the method or way to get all keys existing in Json array.
Regards
Why don't you use a
var jsonObject = {"k1":"v1","k2":"v2","k3":"v3","k4":"v4","k5":"v5"}
instead of your
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
? Then the solution would be so simple: Object.keys(jsonObject).
Try this:
var L = jsonArray.length;
for (var i = 0; i < L; i++) {
var obj = jsonArray[i];
for (var j in obj) {
alert(j);
}
}
I've also made some modifications of your current code (like length caching).
Loop through the object properties, and select the first "real" one (which given your data schema should be the only real one).
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
for (var i = 0; i < jsonArray.length; i++) {
for (var prop in jsonArray[i]) {
if (jsonArray[i].hasOwnProperty(prop)) {
var key = prop;
break;
}
}
alert(key);
}
See How to loop through items in a js object? for an explanation of why it's important to use hasOwnProperty here.
Try this:
jsonArray.reduce(function(keys, element){
for (key in element) {
keys.push(key);
}
return keys;
},[]);
This should also work for multiple keys in the array objects.
If you're supporting old browsers that don't have reduce and map, then consider using a shim.
var id = { "object": "page", "entry": [{ "id": "1588811284674233", "time": 1511177084837, "messaging": [{ "sender": { "id": "1393377930761248" }, "recipient": { "id": "1588811284674233" }, "timestamp": 1511177084553, "message": { "mid": "mid.$cAAX_9pLcfu1mCnGmiVf2Sxd2erI2", "seq": 1882, "text": "a" } }] }] };
function getKey(obj, data) {
//#author dvdieukhtn#gmail.com
var data = data || [];
if (obj) {
var keys = Object.keys(obj);
for (var pos in keys) {
console.log();
data.push(keys[pos]);
if ((obj[keys[pos]].constructor === Array)) {
for (var i = 0; i < obj[keys[pos]].length; i++) {
getKey(obj[keys[pos]][i], data);
}
}
else if (obj[keys[pos]].constructor === Object) {
getKey(obj[keys[pos]], data);
}
}
return data;
}
}
console.log(getKey(id));
I have this JS object:
{
"data": {
"nid": [{
"cid": "32",
"uid": "780",
"comment": "text"
}]
},
"request_status": "found"
}
how can I loop through these items to get comment value ("comment":"text")?
You don't really need to loop to get it. Just do...
var obj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
var text = obj.data.nid[0].comment;
Or if there are several, you can use forEach...
obj.data.nid.forEach(function(val,i) {
alert( val.comment );
});
Or a traditional for loop...
for( var i = 0; i < obj.data.nid.length; i++ ) {
alert( obj.data.nid[i].comment );
}
Or if you want to build an Array, use map...
var arr = obj.data.nid.map(function(val,i) {
return val.comment;
});
Or again a traditional for loop...
var arr = []
for( var i = 0; i < obj.data.nid.length; i++ ) {
arr.push( obj.data.nid[i].comment );
}
Given:
var obj = {
"data": {
"nid": [{
"cid": "32",
"uid": "780",
"comment": "text"
}]
},
"request_status": "found"
};
The direct way to retrieve the comment is:
obj["data"]["nid"][0]["comment"]
// or
obj.data.nid[0].comment
As far as "looping" through the items to get the value, I'm not sure how a loop makes sense. Are you saying you might not know the structure of the object but you know it will have a "comment" field in there somewhere?
The "nid" array only has one item in it - if this was just a sample but really you'll have an array with more values you can loop through that array:
var nid = obj["data"]["nid"], // get a direct reference to the array to save
i; // repeating obj.data.nid everywhere
for (i=0; i < nid.length; i++) {
// do something with the comment in the current item
console.log(nid[i]["comment"]);
}
If you're just referring to that specific object (or if every object you are working with follows that same pattern), then you can just access the value directly:
var theObj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
alert(theObj.data.nid[0].comment);
If you want to do something iterative, then perhaps try this:
var theObj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
for (var index = 0; index < theObj.data.nid.length; index++) {
var item = theObj.data.nid[index];
if (item.comment) {
alert(item.comment);
}
}
Or if you really want to do the entire thing iteratively:
window.searchObj = function(theObj) {
if (theObj.comment) {
alert(theObj.comment);
}
if (theObj instanceof Array) {
searchArray (theObj);
}
else if (theObj instanceof Object) {
for (var key in theObj) {
searchObj(theObj[key]);
}
}
};
window.searchArray = function(theArray) {
for (var index = 0; index < theArray.length; index++) {
var item = theArray[index];
searchObj(item);
}
};
var theObj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
searchObj(theObj);