Я предлагаю это решение, которое не является совершенным и заслуживает улучшений, но оно работает, оно поможет вам начать работу.
Весь приведенный ниже код добавляется в конце функции обновления в файле dndTree.js.
console.log(root); //root contains everything you need
const getCircularReplacer = (deletePorperties) => { //func that allows a circular json to be stringified
const seen = new WeakSet();
return (key, value) => {
if (typeof value === "object" && value !== null) {
if(deletePorperties){
delete value.id; //delete all properties you don't want in your json (not very convenient but a good temporary solution)
delete value.x0;
delete value.y0;
delete value.y;
delete value.x;
delete value.depth;
delete value.size;
}
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
};
var myRoot = JSON.stringify(root, getCircularReplacer(false)); //Stringify a first time to clone the root object (it's allow you to delete properties you don't want to save)
var myvar= JSON.parse(myRoot);
myvar= JSON.stringify(myvar, getCircularReplacer(true)); //Stringify a second time to delete the propeties you don't need
console.log(myvar); //You have your json in myvar
Теперь, когда у вас есть JSON, вы можете:
Скачать новый файл tree.json:
function download(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], {
type: contentType
});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
}
download(myvar, 'tree.json', 'text/plain');
Пример с node.js:
var fs = require('fs');
fs.writeFile("tree.json", myvar, function(err) {
if (err) {
console.log(err);
}
});
Проверьте это для получения дополнительной информации для сохранения файла: Как сохранить JSON в локальный текстовый файл
В Java, если Car
является производным классом Vehicle
, тогда мы можем рассматривать все Cars
как Vehicles
; Автомобиль
- это Автомобиль
. Однако, Список
из Автомобили
также не является Список
из Транспортных средств
. Мы говорим, что List
не является не ковариантным с List
.
Java требует от вас явного указания, когда вы хотите использовать ковариация и контрвариантность с подстановочными знаками, представленными токеном ?
. Посмотрите, где происходит ваша проблема:
List<List<? extends Number>> l = new ArrayList<List<Number>>();
// ---------------- ------
//
// "? extends Number" matched by "Number". Success!
Внутренний Список расширяет номер>
работает, потому что номер
действительно расширяет номер
, поэтому он соответствует «? Extends Number
». Все идет нормально. Что дальше?
List<List<? extends Number>> l = new ArrayList<List<Number>>();
// ---------------------- ------------
//
// "List<? extends Number>" not matched by "List<Number>". These are
// different types and covariance is not specified with a wildcard.
// Failure.
Однако объединенный параметр внутреннего типа List extends Number>
не соответствует List
; типы должны быть точно идентичными . Другой подстановочный знак скажет Java, что этот комбинированный тип также должен быть ковариантным:
List<? extends List<? extends Number>> l = new ArrayList<List<Number>>();
I Я не очень знаком с синтаксисом Java, но, похоже, ваша проблема заключается в следующем:
Вы обязательно должны использовать? при необходимости введите подстановочный знак, как правило, не избегайте его. Например:
public void doThingWithList(List<List<? extends Number>> list);
позволяет вам передать List
или List
.
public void doThingWithList(List<List<Number>> list);
позволяет передавать только аргументы, объявленные как List
. Небольшое различие, да, но использование подстановочного знака является мощным и безопасным . Вопреки тому, как это может показаться, список
не является подклассом или не может быть назначен из List
. Также List
не является подклассом List расширяет номер
, поэтому приведенный выше код не компилируется.
Ваше утверждение не компилируется, поскольку List extends Number>
отличается от типа List
. Первый является супертипом второго.
Вы пробовали это? Здесь я выражаю, что List является ковариантным в своем аргументе типа, поэтому он будет принимать любой подтип из List расширяет номер>
(который включает в себя список <номер>
).
List<? extends List<? extends Number>> aList = new ArrayList<List<Number>>();
Или даже это. Здесь параметр типа для ArrayList с правой стороны совпадает с параметром типа с левой стороны, поэтому дисперсия не является проблемой.
List<List<? extends Number>> aList = new ArrayList<List<? extends Number>>();
Вы можете просто сказать
List<List<Number>> aList = new ArrayList<List<Number>>();
Я склонен по возможности избегайте подстановочных знаков типа ?
. Я считаю, что затраты, понесенные при аннотации типа, не стоят выгоды.