How to not repeat folders with JStree? - javascript

I have a JSON file with some data like this:
dataTree.json =
[
{
"datap": "816816816816816818",
"name": "image1.jpg",
"url": "/files/folder1/test/d2e9c54ceedc9/image1.jpg",
"path": "/files/folder1/test/image1.jpg",
"size": 35969
},
{
"datap": "857022de4fccdcb54623ff6185daae706a47140c",
"name": "image2.jpg",
"url": "/files/folder1/pruebas/85623ff6185d7140c/image2.jpg",
"path": "/files/folder1/pruebas/image2.jpg",
"size": 17689282
},
{
"datap": "b260ec3250420c953a9db41897c34e3551620ec325035516256b2/image3.jpg",
"path": "/files/folder1/test/image3.jpg",
"size": 710632
}
]
In this part I make the operation and the format for jstree
$.getJSON('/dataTree.json', function (response) {
var fullTree = [];
if (response == []){
var refullTree = []
}
else {
var refullTree = [{"id":null,"text":"Root","icon":"tree.png","state":null,"children":[]}]
}
function treeElements(element, tree){
var parts = element.path.split("/");
parts.splice(0,2);
for (var k in parts) {
var count = 0
var part = parts[k];
if (part == "") part = "#";
var item = {"id":null, "text": part, "icon": icon(part), "children": []};
tree.push(item);
tree = item.children;
}
function icon(search){
if (search.indexOf(".png",".jpg") > -1){
return "glyphicon glyphicon-picture" }
else if(search.indexOf("jpg",".jpg") > -1){
return "glyphicon glyphicon-picture" }
}
}
for (var i in response) {
treeElements(response[i], fullTree);
}
refullTree[0]["children"] = fullTree
});
The result is output in this format:
[
{
"id": null,
"text": "Root",
"icon": "tree.png",
"state": null,
"children": [
{
"id": null,
"text": "folder1",
"children": [
{
"id": null,
"text": "test",
"children": [
{
"id": null,
"text": "image1.jpg",
"icon": "glyphicon glyphicon-picture",
"children": []
}
]
}
]
},
{
"id": null,
"text": "folder1",
"children": [
{
"id": null,
"text": "pruebas",
"children": [
{
"id": null,
"text": "image2.jpg",
"icon": "glyphicon glyphicon-picture",
"children": []
}
]
}
]
},
{
"id": null,
"text": "folder1",
"children": [
{
"id": null,
"text": "test",
"children": [
{
"id": null,
"text": "image3.jpg",
"icon": "glyphicon glyphicon-picture",
"children": []
}
]
}
]
}
]
}
]
This tree was produced by jstree, and the three folders have the same name. I do not want to create three folders with the same name, I want that when I find a folder that exists, the data is entered into the that existing folder.
Instead, I want this:

Here is a demo of how to parse this structure: http://jsfiddle.net/DGAF4/506/
Here is the actual parsing code (also visible in the fiddle);
var tmp = {}, i, j, k, l, p1, p2, fin = [];
for(i = 0, j = a.length; i < j; i++) {
p1 = a[i].path.replace(/^\//,'').split('/');
p2 = '';
for(k = 0, l = p1.length; k < l; k++) {
tmp[p2 + '/' + p1[k]] = {
id : p2 + '/' + p1[k],
parent : p2 ? p2 : '#',
text : p1[k]
};
p2 += '/' + p1[k];
}
for(k in a[i]) {
if(a[i].hasOwnProperty(k)) {
tmp[a[i].path][k] = a[i][k];
}
}
if(a[i].path.match(/(jpg|png|jpeg)$/)) {
tmp[a[i].path].icon = "glyphicon glyphicon-picture";
}
}
for(i in tmp) {
if(tmp.hasOwnProperty(i)) {
fin.push(tmp[i]);
}
}
// fin contains the structure in a jstree compatible format

Related

Count number of repetition for values in JSON nested arrays with Javascript

I'm stuck with something I thought would be easy. Let's say I have an object like this. I'm trying to insert in the div each name of the animal tagged and the number of times that tag is in types (for example, cat = 3, etc...)
var animals = '';
animals = {
"types": [
{
"id": "1",
"tags": ["cat"]
},
{
"id": "2",
"tags": ["dog"]
},
{
"id": "3",
"tags": ["cat", "bird", "dog"]
},
{
"id": "4",
"tags": []
},
{
"id": "5",
"tags": ["cat", "bird"]
}
]
}
for (var i = 0; i < animals.length; i++) {
var tags = animals[i].tags;
}
<div class="types">Number of animals:</div>
I'm a beginner with complex JSON objects, any help would be appreciated. It can be vanilla JS or Jquery.
Thanks!
Check out the snippet below, first loop iterates and counts each animal.
Second populates your div
var animals = '';
animals = {
"types": [{
"id": "1",
"tags": ["cat"]
},
{
"id": "2",
"tags": ["dog"]
},
{
"id": "3",
"tags": ["cat", "bird", "dog"]
},
{
"id": "4",
"tags": []
},
{
"id": "5",
"tags": ["cat", "bird"]
}
]
}
var tags = {};
// Iterate over all your items
animals.types.forEach(function(type) {
// Iterate over all the animals in the array
type.tags.forEach(function(tag) {
if (tag in tags) {
// If animal is present, increment the count
tags[tag] = tags[tag] + 1;
} else {
// If animal is not present, add the entry
tags[tag] = 1;
}
})
})
// Iterate over all the animals and add it to the div
for (var animal in tags) {
if (tags.hasOwnProperty(animal)) {
document.getElementsByClassName('types')[0].innerHTML += ' ' + animal + ' ' + tags[animal];
}
}
<div class="types">Number of animals:</div>
You can do like this by using map() method :
var animals = {
"types": [{
"id": "1",
"tags": ["cat"]
},
{
"id": "2",
"tags": ["dog"]
},
{
"id": "3",
"tags": ["cat", "bird", "dog"]
},
{
"id": "4",
"tags": []
},
{
"id": "5",
"tags": ["cat", "bird"]
}
]
};
var count = {};
animals.types.map(function (arr, i) {
arr.tags.map(function (tag, k) {
count[tag] = (count[tag] || 0) + 1;
});
});
console.log(count);
If you use reduce & destrucuring it becomes one liner:
var animals = {
"types": [{
"id": "1",
"tags": ["cat"]
},
{
"id": "2",
"tags": ["dog"]
},
{
"id": "3",
"tags": ["cat", "bird", "dog"]
},
{
"id": "4",
"tags": []
},
{
"id": "5",
"tags": ["cat", "bird"]
}
]
}
console.log(
animals.types.reduce((r,{tags}) => tags.map(tag => r[tag] = (r[tag] || 0) + 1) && r, {})
)
Try this simple way:
var animals = { "types": [ { "id": "1", "tags": ["cat"] }, { "id": "2", "tags": ["dog"] }, { "id": "3", "tags": ["cat", "bird", "dog"] }, { "id": "4", "tags": [] }, { "id": "5", "tags": ["cat", "bird"] } ] }
var finalRes={};
animals.types.map(function(o, i){
o.tags.map(function(p, j){
finalRes[p]=(finalRes[p]||0)+1;
});
});
console.log(finalRes);
Result:
{ cat: 3, dog: 2, bird: 2 }
Sorry, I am typing with mobile phone, slow but correct!
Flatten all tags into single array
Count each tag
Handle tag count as you need
const animals = {
"types": [
{
"id": "1",
"tags": ["cat"]
},
{
"id": "2",
"tags": ["dog"]
},
{
"id": "3",
"tags": ["cat", "bird", "dog"]
},
{
"id": "4",
"tags": []
},
{
"id": "5",
"tags": ["cat", "bird"]
},
],
};
// Flatten all tags into single array
var allTags = [].concat(
...animals.types.map(
(type) => type.tags
)
);
// Count each tag
const tagsCount = {};
allTags.forEach(
(tag) => tagsCount[tag] = tagsCount[tag] ? tagsCount[tag] + 1 : 1
)
// Handle tag count as you need
const app = document.querySelector('#app');
app.innerHTML = Object.keys(tagsCount).map((key) => {
return `<p>${key}: ${tagsCount[key]}</p>`
}).join('');
<h1>Number of Animal Types</h1>
<div id="app"></div>
Basic javascript usage.
// var animals = ''; // not needed
var animals = {
"types": [{
"id": "1",
"tags": ["cat"]
},
{
"id": "2",
"tags": ["dog"]
},
{
"id": "3",
"tags": ["cat", "bird", "dog"]
},
{
"id": "4",
"tags": []
},
{
"id": "5",
"tags": ["cat", "bird"]
}
]
};
var counts = {};
for (var i = 0; i < animals.types.length; i++) { // types is a key in animals object, animals is not an array
var tags = animals.types[i].tags;
if (tags.length > 0) {
for (var j = 0; j < tags.length; j++) {
var tag = tags[j];
if (typeof counts[tag] === 'undefined') {
counts[tag] = 0;
}
counts[tag]++;
}
}
}
console.log(counts);
You could create a hash map for all the tags and increment the count whenever you encounter that tag in that types.tags array
Then loop through the object and append that into your HTML Element
var animals = '';
animals = {
"types": [
{
"id": "1",
"tags": ["cat"]
},
{
"id": "2",
"tags": ["dog"]
},
{
"id": "3",
"tags": ["cat", "bird", "dog"]
},
{
"id": "4",
"tags": []
},
{
"id": "5",
"tags": ["cat", "bird"]
}
]
}
let types = animals.types;
var counts = {};
for (var i = 0; i < types.length; i++) {
types[i].tags.forEach((x) => {
counts[x] = (counts[x] || 0)+1;
});
}
console.log(counts);
<div class="types">Number of animals:</div>

custom jstree JSON data parse into tree

i have a simple JSON data which is this :
[
"env/child1/env/key1",
"env/child1/key1",
"env/child1/key2",
"env/child1/",
"env/child2/key1",
"env/child2/key2",
"env/child2/",
"env/"
]
how can i make jsTree understands this tree and draw the tree ?
env
child1
key1
key2
do i need to write a custom parsing function or is there a ready way for that.
tree = {
'core' : {
'data' : [
]
}
}
data = [
"env/child1/env/key1",
"env/child1/key1",
"env/child1/key2",
"env/child1/",
"env/child2/key1",
"env/child2/key2",
"env/child2/",
"env/"
];
minlen = -1;
picked = "";
for(i =0; i<data.length; i++) {
if(data[i].length < minlen || minlen == -1) {
minlen = data[i].length;
picked = data[i];
}
}
tree.core.data.push({ "id" : picked, "parent" : "#", "text" : picked })
xdata = data
xdata.splice(xdata.indexOf(picked), 1)
for(i =0; i<xdata.length; i++) {
name = xdata[i]
parent = ""
if(name.substr(name.length-1,1) == '/') {
xname = name.substr(0,name.length-1);
parent = xname.substr(0,xname.lastIndexOf("/")+1)
} else {
parent = name.substr(0,name.lastIndexOf("/")+1)
}
tree.core.data.push({ "id" : name, "parent" : parent, "text" : name })
}
console.log(tree);
I followed the alternative JSON format.
Result:
{
"core": {
"data": [
{
"id": "env/",
"parent": "#",
"text": "env/"
},
{
"id": "env/child1/env/key1",
"parent": "env/child1/env/",
"text": "env/child1/env/key1"
},
{
"id": "env/child1/key1",
"parent": "env/child1/",
"text": "env/child1/key1"
},
{
"id": "env/child1/key2",
"parent": "env/child1/",
"text": "env/child1/key2"
},
{
"id": "env/child1/",
"parent": "env/",
"text": "env/child1/"
},
{
"id": "env/child2/key1",
"parent": "env/child2/",
"text": "env/child2/key1"
},
{
"id": "env/child2/key2",
"parent": "env/child2/",
"text": "env/child2/key2"
},
{
"id": "env/child2/",
"parent": "env/",
"text": "env/child2/"
}
]
}
}
The above data missing parent "env/child1/env/" for child "env/child1/env/key1"
1. correct as follow:
data = [
"env/child1/env/"
"env/child1/env/key1",
"env/child1/key1",
"env/child1/key2",
"env/child1/",
"env/child2/key1",
"env/child2/key2",
"env/child2/",
"env/"
];
The complete code for parent getting the children's values as below:
https://github.com/peterhchen/700-jstree/blob/master/08_PathJSON/0802_PathChild2ParentValueHier.htm

Sorting JSON alphabetically by first letter

I have a JSON like this:
[
{
"id": 1,
"slug": "abakan",
"name": "Абакан"
},
{
"id": 4,
"slug": "almetevsk",
"name": "Альметьевск"
},
{
"id": 10,
"slug": "astrahan",
"name": "Астрахань"
},
{
"id": 11,
"slug": "barnaul",
"name": "Барнаул"
},
...
]
And getting this by this method:
public function getCities()
{
$cities = City::mainCities()->get(['id', 'slug', 'name']);
return response()->json($cities);
}
How can i sort this list alphabetically and with their letters. For example:
"A": [
{
"id": 1,
"slug": "abakan",
"name": "Абакан"
},
{
"id": 4,
"slug": "almetevsk",
"name": "Альметьевск"
}
],
"B": [
{
"id": 11,
"slug": "barnaul",
"name": "Барнаул"
},
...
]
and so on...
I have Laravel on the backend and VueJS on front.
My solution:
var cities = [
{ id: 1, slug: "abakan", name: "Абакан" },
{ id: 4, slug: "almetevsk", name: "Альметьевск" },
{ id: 11, slug: "barnaul", name: "Барнаул" },
{ id: 10, slug: "astrahan", name: "Астрахань" }
];
cities.sort(function(a, b) {
return a.slug[0].localeCompare(b.slug[0]);
});
var newCities = {};
for (var i = 0; i < cities.length; i++) {
var c = cities[i].slug[0].toUpperCase();
if (newCities[c] && newCities[c].length >= 0)
newCities[c].push(cities[i]);
else {
newCities[c] = [];
newCities[c].push(cities[i]);
}
}
console.log(newCities);
This works for me:
var items = [
{
"id": 11,
"slug": "barnaul",
"name": "Барнаул"
},
{
"id": 1,
"slug": "abakan",
"name": "Абакан"
},
{
"id": 4,
"slug": "almetevsk",
"name": "Альметьевск"
},
{
"id": 10,
"slug": "astrahan",
"name": "Астрахань"
}
];
var sortedItems = items.sort((a, b) => a.slug.localeCompare(b.slug));
var results = {};
for (var i = 0; i < 26; i++) {
var char = String.fromCharCode(97 + i);
var bigChar = char.toUpperCase();
results[bigChar] = [];
for (var s = 0; s < sortedItems.length; s++) {
if (sortedItems[s].slug.startsWith(char)) {
results[bigChar].push(sortedItems[s]);
}
}
}
console.log(results)

Continue add items from array until end loop

I have an object like this:
var Object = {
"id": "Siplus",
"name":"Siplus",
"icon":"forum"
},
{
"id": "Recent",
"name":"Recent Activities",
"icon": "restore"
},
{
"id": "jobList",
"name":"Job List",
"icon": "briefcase"
},
{
"id": "Favourites",
"name":"Favourites",
"icon": "star"
},
{
"id": "searchQuote",
"name":"Search Quotes",
"icon": "binoculars"
},
{
"id": "orderStatus",
"name":"Order Status",
"icon": "clock"
};
I have another array Like this
var array = [1,2,3];
I adding array values to object using this code:
for (var i = 0; i < object.length; i++) {
object[i].number = array[i];
}
I am getting result like this:
var Object = {
"id": "Siplus",
"name":"Siplus",
"icon":"forum",
"number":1
},
{
"id": "Recent",
"name":"Recent Activities",
"icon": "restore",
"number":2
},
{
"id": "jobList",
"name":"Job List",
"icon": "briefcase",
"number":3
},
{
"id": "Favourites",
"name":"Favourites",
"icon": "star",
"number":undefined
},
{
"id": "searchQuote",
"name":"Search Quotes",
"icon": "binoculars",
"number":undefined
},
{
"id": "orderStatus",
"name":"Order Status",
"icon": "clock",
"number":undefined
};
I wanted like this :
var Object = {
"id": "Siplus",
"name":"Siplus",
"icon":"forum",
"number":1
},
{
"id": "Recent",
"name":"Recent Activities",
"icon": "restore",
"number":2
},
{
"id": "jobList",
"name":"Job List",
"icon": "briefcase",
"number":3
},
{
"id": "Favourites",
"name":"Favourites",
"icon": "star",
"number":1
},
{
"id": "searchQuote",
"name":"Search Quotes",
"icon": "binoculars",
"number":2
},
{
"id": "orderStatus",
"name":"Order Status",
"icon": "clock",
"number":3
};
Is their any way to get repeat the number instead of getting "undefined"
Please help me for this
You could map your input objects by adding the right value from array thanks to the modulo calculus
var data = [{
"id": "Siplus",
"name":"Siplus",
"icon":"forum"
},
{
"id": "Recent",
"name":"Recent Activities",
"icon": "restore"
},
{
"id": "jobList",
"name":"Job List",
"icon": "briefcase"
},
{
"id": "Favourites",
"name":"Favourites",
"icon": "star"
},
{
"id": "searchQuote",
"name":"Search Quotes",
"icon": "binoculars"
},
{
"id": "orderStatus",
"name":"Order Status",
"icon": "clock"
}];
var array = [1,2,3];
res = data.map((x,i) => {
x.number = array[i % array.length]
return x;
})
console.log(res);
The size of array is 3 while that of object is more - a solution would be to use:
object[i].number = array[i % array.length];
See demo below:
var object=[{"id":"Siplus","name":"Siplus","icon":"forum"},{"id":"Recent","name":"Recent Activities","icon":"restore"},{"id":"jobList","name":"Job List","icon":"briefcase"},{"id":"Favourites","name":"Favourites","icon":"star"},{"id":"searchQuote","name":"Search Quotes","icon":"binoculars"},{"id":"orderStatus","name":"Order Status","icon":"clock"}]
var array = [1, 2, 3];
for (var i = 0; i < object.length; i++) {
object[i].number = array[i % array.length];
}
console.log(object);
.as-console-wrapper{top:0;max-height:100%!important;}
you could use an additional var.
for (var i = 0, j = 0; i < object.length; i++) {
j++
if(j > array.length){j=0}
object[i].number = array[j];
}
var arrLength = array.length;
for (var i = 0, j = 0; i < object.length; i++, j++) {
if (i >= arrLength ) {
j = 0;
}
object[i].number = array[j];
}
You could use a temporary value to point to the numbers array like this:
var temp = 0;
for (var i = 0; i < object.length; i++) {
object[i].number = array[temp];
if(temp == array.length)
temp = 0;
else
temp++;
}

Json Nested Object Array to Table

I have a json file, there is an array of objects. In the first object is a 2nd array with +/- 200 objects. Is there a possibility to show the 2nd array in a new table in the last row of the first table?
As seen here, there should be a nested table in the column: "Friends"
http://jsfiddle.net/TqbMC/
The html is:
<body onLoad="buildHtmlTable()">
<table id="excelDataTable" border="1">
</table>
</body>
The rest of the code is:
var myList=[{
"id": "220439",
"name": "Bret Taylor",
"friends": {
"data": [
{
"id": "100003461417780",
"name": "Pedro Fernandes"
},
{
"id": "100004448132997",
"name": "Tatiane Rodrigues"
},
{
"id": "100002608573875",
"name": "Gerson Yoody"
},
{
"id": "100003532942622",
"name": "Brennen Roup"
},
{
"id": "100003910478450",
"name": "Maruxita Gomez"
},
{
"id": "100003035179424",
"name": "Ekta Vaghasia"
},
{
"id": "100003034655176",
"name": "Nikita Adam"
},
{
"id": "100004269720826",
"name": "Lukas Ks"
},
{
"id": "100004489472386",
"name": "Hong Finozaza"
},
{
"id": "1436623789",
"name": "Dianita M Ct"
},
{
"id": "100004324535652",
"name": "Ana Paula"
},
{
"id": "100004433135086",
"name": "Caroline Geovannini"
},
{
"id": "100004081013147",
"name": "Ryan Bispo Silva"
},
{
"id": "1697844686",
"name": "Louann Hyatt Clark"
},
{
"id": "100003283377051",
"name": "Ysabel Salazar"
},
{
"id": "100003398360349",
"name": "Ty SoHigh Walker"
},
{
"id": "100001201489463",
"name": "Dicu Andrei D"
},
{
"id": "100001811128458",
"name": "Cristy Torres Castellanos"
},
{
"id": "1693121601",
"name": "Jasim Amit"
},
{
"id": "100001966217366",
"name": "Candy Chhokar"
},
{
"id": "100004096284395",
"name": "Stefania Bilska"
},
{
"id": "100004084157244",
"name": "Papah Noval"
},
{
"id": "1791202672",
"name": "Bianca Agostina Gherardini"
},
{
"id": "100000825894241",
"name": "Usman Faiz"
},
{
"id": "100002424916440",
"name": "Muhammad Tajminur Rahman"
}
],
"paging": {
"next": "https://graph.facebook.com/99394368305/likes?limit=25&after=MTAwMDAyNDI0OTE2NDQw"
}
}
}];
// Builds the HTML Table out of myList json data from Ivy restful service.
function buildHtmlTable() {
var columns = addAllColumnHeaders(myList);
for (var i = 0 ; i < myList.length ; i++) {
var row$ = $('<tr/>');
for (var colIndex = 0 ; colIndex < columns.length ; colIndex++) {
var cellValue = myList[i][columns[colIndex]];
if (cellValue == null) { cellValue = ""; }
row$.append($('<td/>').html(cellValue));
}
$("#excelDataTable").append(row$);
}
}
// Adds a header row to the table and returns the set of columns.
// Need to do union of keys from all records as some records may not contain
// all records
function addAllColumnHeaders(myList)
{
var columnSet = [];
var headerTr$ = $('<tr/>');
for (var i = 0 ; i < myList.length ; i++) {
var rowHash = myList[i];
for (var key in rowHash) {
if ($.inArray(key, columnSet) == -1){
columnSet.push(key);
headerTr$.append($('<th/>').html(key));
}
}
}
$("#excelDataTable").append(headerTr$);
return columnSet;
}
(the data comes from the facebook graph api)
you can access inner data in this way: myList[0].friends.data[i].id and myList[0].friends.data[i].name, just iterate until myList[0].friends.data.length is reached and build whatever structure you want - for example create table row for each friend with two td - one for id and one for name – magyar1984
http://jsfiddle.net/6v8Ew/1/
for (var x = 0 ; x < myList[0].friends.data.length ; x++){
$line.append( $( "<td></td>" ).html( myList[0].friends.data[x].id ) );
}

Categories

Resources