Small issue in javascript array object logic - javascript

I have an json array as below.If I find atleast one object with status as Active I need to set response =true or else false.I tried below but didnt worked .can someone help.
arr=[{"id":"1","status":"active"},{"id":"2","status":"complete"},
{"id":"3","status":"complete"}]
for (var i = 0; i < arr.len; i++) {
if (arr[i].status == "active") {
response = true;
} else {
response = false;
}
}
console.log(response);

Use Array#some to check if at least one element got status property with active value.
var arr = [{"id":"1","status":"active"},{"id":"2","status":"complete"},
{"id":"3","status":"complete"}],
response = arr.some(v => v.status == 'active');
console.log(response);

You set your response to true, don't break the loop and then set it to false again when you meet another value.
You may simply set initial condition and then break when you find an item. You can actually even not break when you find an item, but it is useless to continue iteration when already found an item.
var arr = [{
"id": "1",
"status": "active"
}, {
"id": "2",
"status": "complete"
},
{
"id": "3",
"status": "complete"
}
];
var response = false;
for (var i = 0; i < arr.length; i++) {
if (arr[i].status == "active") {
response = true;
break;
}
}
console.log(response);
Another elegant way is to use function and make a short-circuit return:
var arr = [{
"id": "1",
"status": "active"
}, {
"id": "2",
"status": "complete"
},
{
"id": "3",
"status": "complete"
}
];
function hasActiveStatus(a) {
for (var i = 0; i < a.length; i++) {
if (a[i].status == "active") {
return true;
}
}
return false;
}
var response = hasActiveStatus(arr);
console.log(response);
Note that you had .len for some reason, I have replaced it with correct .length.
Even more elegant way is to use Array.prototype.some:
var arr = [{
"id": "1",
"status": "active"
}, {
"id": "2",
"status": "complete"
},
{
"id": "3",
"status": "complete"
}
];
var response = arr.some(function(x) { return x.status === "active"; });
console.log(response);

var response = false;
var arr=[{"id":"1","status":"active"},{"id":"2","status":"complete"},
{"id":"3","status":"complete"}]
for (var i = 0; i < arr.length; i++) {
if (arr[i].status == "active") {
response = true;
break;
}
}
console.log(response);

Related

Loop through arrayObjects with condition Javascript

I found a nice example on here showing how to look through arrayObjects with a condition but I have a question.
As is stands its console.logging every time it the condition is false. Is it possible to only console.log once when its finished looping through everything.
var arrayObjects = [{
"building": "A",
"status": "good"
},
{
"building": "B",
"status": "horrible"
}
];
for (var i = 0; i < arrayObjects.length; i++) {
console.log(arrayObjects[i]);
for (key in arrayObjects[i]) {
if (key == "status" && arrayObjects[i][key] == "good") {
console.log(key + "->" + arrayObjects[i][key]);
} else {
console.log("nothing found");
}
}
}
Simply use .length with if condition.
var arrayObjects = [{
"building": "A",
"status": "good"
},
{
"building": "B",
"status": "horrible"
}
];
for (var i = 0; i < arrayObjects.length; i++) {
console.log(arrayObjects[i]);
if( i === arrayObjects.length-1 ) {
console.log("nothing found");
}
}
I'm assuming that you want it to print Nothing found when nothing's really found, not even a single thing..
Then, you can try this.
var arrayObjects = [{"building":"A", "status":"good"},
{"building":"B","status":"horrible"}];
var isFound = false;
for (var i=0; i< arrayObjects.length; i++) {
console.log(arrayObjects[i]);
for(key in arrayObjects[i]) {
if (key == "status" && arrayObjects[i][key] == "good") {
isFound = true
console.log(key + "->" + arrayObjects[i][key]);
}
}
}
if (isFound === false){
console.log("nothing found");
}
You can use the some or filter method of array.
var arrayObjects = [{"building":"A", "status":"good"},
{"building":"B","status":"horrible"}];
const found = arrayObjects.some(it => it.status === 'good')
if (found) {
console.log('found')
}
const items = arrayObjects.filter(it => it.status === 'good')
if (items.length) {
console.log('found')
}
If you're willing to refactor you code, you can save on time complexity by using just one loop with Array.reduce()
var arrayObjects = [{
"building": "A",
"status": "good"
},
{
"building": "B",
"status": "horrible"
}
];
const foundKeys = arrayObjects.reduce((bool, key) => {
console.log(key)
if (key.status === "good") {
console.log("status ->", key.status);
bool = true
}
return bool
}, false)
if (!foundKeys) {
console.log("Nothing found")
}
Another declarative way solution:
const arrayObjects = [
{ "building": "A", "status": "good" },
{ "building": "B", "status": "horrible" },
];
const checkCondition = (arr, key = 'status', value ='good') => {
const result = arr.find((obj) => obj[key] === value);
return result
? `${key} -> ${result[key]}`
: "nothing found";
};
console.log(checkCondition(arrayObjects)); //status -> good
console.log(checkCondition(arrayObjects, 'building', 'B')); //building -> B
console.log(checkCondition(arrayObjects, 'building', 'C')); //nothing found

How to get an JSON Object based in key using jquery

I'm using jsTree and have tree an structured JSON object.
[{
"id": 1,
"text": "TEXT_ONE",
"children": [
{
"id": 2,
"text": "TEXT_TWO",
"children": [
{
"id": 3,
"text": "TEXT_THREE",
"children": [
]
},
{
"id": 4,
"text": "TEXT_FOUR",
"children": [
]
}
]
},
{
"id": 5,
"text": "TEXT_FIVE",
"children": [
]
}
]
},
{
"id": 6,
"text": "TEXT_SIX",
"children": [ ]
}]
I want to get the the object based on the "id" of the object.
For example if i have a function getIdFromTree(3) it will return me the JSON object as following:
{
"id": 3,
"text": "TEXT_THREE",
"children": []
},
How I do that in Javascript/JQuery?
Try this
function getObjById (tree, id) {
if(tree.id === id) {
return tree;
}
if(tree.children) {
for(var i = 0, l = tree.children.length; i < l; i++) {
var returned = getObjById(tree.children[i], id);
if(returned) {
// so that the loop doesn't keep running even after you find the obj
return returned;
}
}
}
}
Call this as follows
getObjById({children: tree}, 3); // tree is the array object above.
function findById (tree, id) {
var result, i;
if (tree.id && tree.id === id) {
result = tree;
// Revalidate array list
} else if (tree.length) {
for (i = 0; i < tree.length; i++) {
result = findById(tree[i], id);
if (result) {
break;
}
}
// Check childrens
} else if (tree.children) {
result = findById(tree.children, id);
}
return result;
}
Use filter Methode off Array
data.filter(function (obj){ obj.id== 3});
try this.... Es6
function *getObjectById(data, id) {
if (!data) return;
for (let i = 0; i< data.length; i++){
let val = data[i];
if (val.id === id) yield val;
if (val.children) yield *getObjectById(val.children , id);
}
}
now
getObjectById(arrayOfObjects, id).next().value;
try this with most effective and efficient way..
function getObjById (tree, id) {
for(var i= 0;i<tree.length;i++)
{
if(tree[i].id===id)
{
return tree[i];
}
if(tree[i].children)
{
var returned = getObjById(tree[i].children,id);
if(returned!= undefined)
return returned;
}
}
};
link:
https://jsfiddle.net/aa7zyyof/14/

Loop through all documents in a nested function

I started using Couchbase for a new project of mine and I hope you can help me solve a problem.
I have two types of documents in my bucket. For example:
{
"id": "A1",
"name": "Name of A",
"type": "A"
}
and
{
"id": "B1",
"name": "Name of B",
"type": "B",
"parentIDs": ["A1", "A4", "A5"]
}
I want to create a view with the following result:
{
"id": "A1",
"name": "Name of A",
"type": "A",
"children": [
{JSON document of child 1},
{JSON document of child 2},
{JSON document of child 3}
]
}
I started to write a function and a nested one, which should iterate through all documents but I must surrender... Can you help me?
function (doc, meta)
{
if(doc.type == "A")
{
emit(doc, GetAllSites(doc));
}
function GetAllSites(doc)
{
var sites = [];
for(var i = 0; i < doc.length; i++)
{
sites.push(doc.id);
}
return sites;
}
}
Thanks
-----------------UPDATE-----------------
I solved my problem this way:
// map function
function (doc, meta)
{
emit(meta.id, doc);
}
// reduce function
function (key, values, rereduce)
{
var result = [];
for(var i = 0; i < values.length; i++)
{
var val1 = values[i];
if(val1.type != "A")
continue;
val1.childrenIDs = [];
for(var j = 0; j < values.length; j++)
{
var val2 = values[j];
switch(val2.type)
{
case "B":
if(contains(val2.parentIDs, val1.id))
val1.childrenIDs.push(val2);
break;
default:
break;
}
}
result.push(val1);
}
return result;
function contains(a, obj) {
var i = a.length;
while (i--) {
if (a[i] === obj) {
return true;
}
}
return false;
}
}
May be no "blue-print" solution but it works and I'll optimize it later. :-)
You can't use nested functions, in you case I'll recommend to use reduce function after map function.
So you need paste you GetAllSites function code to reduce
And don't forget to realize rereduse logic

How to find object by id in array of objects?

I have this json file:
var data = [{
"id": 0,
"parentId": null,
"name": "Comapny",
"children": [
{
"id": 1235,
"parentId": 0,
"name": "Experiences",
"children": [
{
"id": 3333,
"parentId": 154,
"name": "Lifestyle",
"children": []
},
{
"id": 319291392,
"parentId": 318767104,
"name": "Other Experiences",
"children": []
}
]
}
]
}];
I need to find object by id. For example if need to find an object with id:319291392, I have to get:
{"id": 319291392,"parentId": 318767104,"name": "Other Experiences","children": []}
How can I do that?
I tried to use this function:
function findId(obj, id) {
if (obj.id == id) {
return obj;
}
if (obj.children) {
for (var i = 0; i < obj.children.length; i++) {
var found = findId(obj.children[i], id);
if (found) {
return found;
}
}
}
return false;
}
But it doesn't work as it's an array of objects.
If your starting point is an array, you want to invert your logic a bit, starting with the array rather than with the object:
function findId(array, id) {
var i, found, obj;
for (i = 0; i < array.length; ++i) {
obj = array[i];
if (obj.id == id) {
return obj;
}
if (obj.children) {
found = findId(obj.children, id);
if (found) {
return found;
}
}
}
return false; // <= You might consider null or undefined here
}
Then
var result = findId(data, 319291392);
...finds the object with id 319291392.
Live Example
This should work for you:-
var serachById = function (id,data) {
for (var i = 0; i < data.length; i++) {
if(id==data[i].id)
return data[i];
if(data[i].children.length>0)
return serachById(id,data[i].children);
};
return null;
}
console.log(serachById(0,data));
Here is another simple solution using object notation.
This solution will work even if you decide to get rid of teh array and use object notation later on. so the code will remain the same.
It will also support the case when you have element with no children.
function findId(obj, id) {
var current, index, reply;
// Use the object notation instead of index.
for (index in obj) {
current = obj[index];
if (current.id === id) {
return current;
}
reply = findId(current.children, id);
if (reply) {
return reply;
}
// If you reached this point nothing was found.
console.log('No match found');
}
}
console.log(findId(data, 319291392));
do it so:
for (var obj in arr) {
if(arr[obj].id== id) {
console.log(arr[obj]);
}
}

How can I remove duplication from list

I have this kind of list from my web service. I want to eliminate username duplication:
Mylist = [{
"username": "Plr1",
"is_online": true,
"email": null,
"message": null,
"direction": 1,
"image_url": ""
}, {
"username": "plr2",
"is_online": false,
"email": "",
"message": null,
"direction": 1,
"image_url": ""
}, {
"username": "plr1",
"is_online": false,
"email": "",
"message": null,
"direction": 1,
"image_url": null
}];
Is there a function that allows me to remove duplicated values (one of elements=Plr1)?
You can use Array.filter
var Mylist = [{"username":"Plr1","is_online":true,"email":null,"message":null,"direction":1,"image_url":""},{"username":"plr2","is_online":false,"email":"","message":null,"direction":1,"image_url":""},{"username":"plr1","is_online":false,"email":"","message":null,"direction":1,"image_url":null} ];
var keys = [];
var newList = Mylist.filter(
function(x){
var val = x.username.toLowerCase();
if (!keys[val]) {
keys[val] = true;
return true;
}
return false;
}
);
keys = null;
console.log(newList);
It will not work in older browsers out of the box. If you look at the link I posted to above, there is a pollyfill to make them work.
DEMO: http://jsfiddle.net/abc123/ZgYbB/
NOTE: The last for loop is just to show that items were removed and what is left in the array.
JS:
var Mylist= [{"username":"Plr1","is_online":true,"email":null,"message":null,"direction":1,"image_url":""},{"username":"plr2","is_online":false,"email":"","message":null,"direction":1,"image_url":""},{"username":"plr1","is_online":false,"email":"","message":null,"direction":1,"image_url":null} ];
for (var i = 0; i < Mylist.length; i++) {
for(var j = i + 1; j < Mylist.length; j++) {
if(Mylist[i].username.toLowerCase() == Mylist[j].username.toLowerCase())
Mylist.splice(j, 1);
}
}
//Not needed just proof that items were removed.
for (var i = 0; i < Mylist.length; i++) {
alert(Mylist[i].username);
}
This will do what you want (assuming you're looking for case-insensitive comparison of usernames).
EDIT to add Demo: http://jsfiddle.net/vBZhR/
var Mylist= [{"username":"Plr1","is_online":true,"email":null,"message":null,"direction":1,"image_url":""},{"username":"plr2","is_online":false,"email":"","message":null,"direction":1,"image_url":""},{"username":"plr1","is_online":false,"email":"","message":null,"direction":1,"image_url":null} ];
dedupe(Mylist);
function dedupe(list) {
var usernames = {};
for (var i in list) {
if (usernames[list[i].username.toLowerCase()]) {
list.splice(i, 1);
} else {
usernames[list[i].username.toLowerCase()] = true;
}
}
return list;
}

Categories