Страницы

Поиск по вопросам

вторник, 7 мая 2019 г.

Нужно вывести древовидную структуру многомерного массива объектов

Есть массив обьектов:
var testObject = [ { name: 'Название 1', value: 2, childnodes: [ { name: 'Название 4', value: 25, childnodes: [ { name: 'Название 9', value: 32, childnodes: [ ] }, { name: 'Название 10', value: 0, childnodes: [ { name: 'Название 11', value: 5, childnodes: [ ] }, { name: 'Название 12', value: 2267, childnodes: [ { name: 'Название 15', value: 35, childnodes: [ { name: 'Название 16', value: 55, childnodes: [ ] } ] } ] } ] } ] }, { name: 'Название 5', value: 12, childnodes: [ ] }, { name: 'Название 6', value: 45, childnodes: [ ] }, ] }, { name: 'Название 2', value: 32, }, { name: 'Название 3', value: 7, childnodes: [ { name: 'Название 7', value: 12334, childnodes: [ { name: 'Название 13', value: 122, childnodes: [ ] } ] }, { name: 'Название 8', value: 86, childnodes: [ { name: 'Название 14', value: 222, childnodes: [ ] } ] } ] } ];
Задание состоит в том чтоб с помощью знаков псевдографики вывести древовидную структуру обьекта типа:
// ├ Название 1 // │ ├ Название 4 // │ │ ├ Название 9 // │ │ └ Название 10 // │ │ ├ Название 11 // │ │ └ Название 12 // │ │ └ Название 15 // │ │ └ Название 16 // │ ├ Название 5 // │ └ Название 6 // ├ Название 2 // └ Название 3 // ├ Название 7 // │ └ Название 13 // └ Название 8 // └ Название 14
Что я "нашаманил" на данный момент:
var symbols = Array("├", "│", "└"); //массив символов в качестве префикса для значений function buildItem(item){ var сontainer = item.name+ "
"; if( item.childnodes ) { for (var i = 0; i < item.childnodes.length; i++){ if (i < item.childnodes.length-1 && item.childnodes.length!==0) container += ( symbols[0]+ buildItem(item.childnodes[i])); else container+=(symbols[2] + buildItem(item.childnodes[i])); }; container+=symbols[1]; } return container; } var content = Array(); for (var i = 0; i < testObject.length; i++) { content[i] = buildItem(testObject[i]); }; var str = content.join("
"); console.log(str);
Результат:
Название 1 ├ Название 4 ├ Название 9 │ └ Название 10 ├ Название 11 │ └ Название 12 └ Название 15 └ Название 16 │ │ │ │ │ ├ Название 5 │ └ Название 6 │ │ Название 2 Название 3 ├ Название 7 └ Название 13 │ │ └ Название 8 └ Название 14 │ │ │
Тоесть работает код не совсем так, как хотелось бы, даже не так как надо. Суть вопроса: я вроде как и ошибку понимаю, что в первом вызове функции в принципе все хорошо, но последующая рекурсия не дает желаемого результата; прошу обьясните где я ошибаюсь, буду очень благодарен


Ответ

При печати очередного узла, перед ним нужно напечать префикс, который будет содержать связи его предков с их сиблингами. Можно заметить 2 вещи:
Для всех детей одного узла префикс будет один и тот же, поэтому его можно накапливать в параметре рекурсивной процедуры; Если узел является последним ребенком, то для него линию вниз рисовать не нужно.
Получается как-то так:
function buildTree(tree, prefix) { if (typeof prefix === 'undefined') prefix = ''; var result = ''; tree.forEach(function(e, i) { var lastNode = i == tree.length - 1; result += prefix + (lastNode ? '└' : '├') + ' ' + e.name + '
'; if (e.childnodes) result += buildTree(e.childnodes, prefix + (lastNode ? ' ' : '|') + ' '); }); return result; }
Результат:
├ Название 1 | ├ Название 4 | | ├ Название 9 | | └ Название 10 | | ├ Название 11 | | └ Название 12 | | └ Название 15 | | └ Название 16 | ├ Название 5 | └ Название 6 ├ Название 2 └ Название 3 ├ Название 7 | └ Название 13 └ Название 8 └ Название 14
function buildTree(tree, prefix) { if (typeof prefix === 'undefined') prefix = ''; var result = ''; tree.forEach(function(e, i) { var lastNode = i == tree.length - 1; result += prefix + (lastNode ? '└' : '├') + ' ' + e.name + '
'; if (e.childnodes) result += buildTree(e.childnodes, prefix + (lastNode ? ' ' : '|') + ' '); }); return result; } var testObject = [{ name: 'Название 1', value: 2, childnodes: [{ name: 'Название 4', value: 25, childnodes: [{ name: 'Название 9', value: 32, childnodes: [] }, { name: 'Название 10', value: 0, childnodes: [{ name: 'Название 11', value: 5, childnodes: [] }, { name: 'Название 12', value: 2267, childnodes: [{ name: 'Название 15', value: 35, childnodes: [{ name: 'Название 16', value: 55, childnodes: [] }] }] }] }] }, { name: 'Название 5', value: 12, childnodes: [] }, { name: 'Название 6', value: 45, childnodes: [] }, ] }, { name: 'Название 2', value: 32, }, { name: 'Название 3', value: 7, childnodes: [{ name: 'Название 7', value: 12334, childnodes: [{ name: 'Название 13', value: 122, childnodes: [] }] }, { name: 'Название 8', value: 86, childnodes: [{ name: 'Название 14', value: 222, childnodes: [] }] }] }]; document.body.innerHTML = buildTree(testObject).split('
').join('
'); body { font-family: monospace; white-space: pre; }

Сервер-клиент на Java

Необходимо сделать Сервер-Клиент.
Со стороны сервера - таблица с именами работников и их ID .
Со стороны клиента - программа для добавления нового сотрудника и вытягивания всей таблицы.
Просить реализации было бы сверхнаглостью, поэтому прошу советов и рекомендаций, так как ни разу не сталкивался с этим.


Ответ

Если хотите писать велосипед, то вот самый быстрый на руку вариант клиент-серверного взаимодействия.
Сервер:
class TCPServer{ public static void main(String argv[]) throws Exception{ String clientSentence; String capitalizedSentence; ServerSocket welcomeSocket = new ServerSocket(6789);
while(true){ Socket connectionSocket = welcomeSocket.accept(); BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); clientSentence = inFromClient.readLine(); System.out.println("Received: " + clientSentence); capitalizedSentence = clientSentence.toUpperCase() + '
'; outToClient.writeBytes(capitalizedSentence); } } }
Клиент:
class TCPClient{ public static void main(String argv[]) throws Exception{ String sentence; String modifiedSentence; BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in)); Socket clientSocket = new Socket("localhost", 6789); DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); sentence = inFromUser.readLine(); outToServer.writeBytes(sentence + '
'); modifiedSentence = inFromServer.readLine(); System.out.println("FROM SERVER: " + modifiedSentence); clientSocket.close(); } }
Если нужно нормальное решение, то сервлеты, или какую-то библиотеку вроде netty
Для работы с базой использовать какую-нибудь ORM вроде Hibernate

C# пробелы после значения в таблице после загрузки из локальной базы данных

В Visual Studio 2015 сгенерировал локальную базу данных, добавил datagrid и привязал его к bindingSource. Все данных сохраняются и загружаются, но после загрузки добавляются пробелы к тексту. К примеру: в поле nchar(10) "hhhh__________".Там где "_" это пробелы. Спасибо


Ответ

для nvarchar память выделяться во время заполнения строки символами, для vchar - она уже выделена размерностью.
nchar [ ( n ) ]
Строковые данные постоянной длины в Юникоде. Параметр n определяет длину строки и должен иметь значение от 1 до 4000. Размер при хранении составляет удвоенное значение n в байтах. Если кодовая страница параметров сортировки использует двухбайтовые символы, размер хранения остается равным n байт. В зависимости от символьной строки для хранения n символов может понадобиться менее n байт. По стандарту ISO синонимами для nchar являются national char и national character..
nvarchar [ ( n | max ) ]
Строковые данные переменной длины в Юникоде. Параметр n определяет длину строки и должен иметь значение от 1 до 4000. Значение max указывает, что максимальный размер при хранении составляет 2^31-1 байт (2 ГБ). Размер хранилища в байтах вдвое больше числа введенных символов + 2 байта. По стандарту ISO синонимами для типа nvarchar являются типы national char varying и national character varying.

Как поменять блоки местами без правки html?

Есть резиновый блок со старой(зачеркнутой) и новой ценой. Как поменять цены местами, чтобы сначала была новая, а потом старая без правки html, чтобы блоки оставались резиновыми и по располагались по центру страницы? фидл
.price { text-align: center; padding: 0 25px; display: block; }

20.170 руб 19.162 руб


Ответ

Про FlexBox: на русском и английском
Поддержка FlexBox caniuse.com

1
#order
Применяется к: дочернему элементу / flex-элементу.
По умолчанию flex-элементы располагаются в исходном порядке. Тем не менее, свойство order может управлять порядком их расположения в контейнере.
.price { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; text-align: center; padding: 0 25px; } .price ins { -webkit-box-ordinal-group: 2; -webkit-order: 1; -ms-flex-order: 1; order: 1; } .price del { -webkit-box-ordinal-group: 3; -webkit-order: 2; -ms-flex-order: 2; order: 2; }

20.170 руб 19.162 руб

2
*{ box-sizing: border-box; } .price { display: block; padding: 0 25px; } .price ins { float: left; width: 50%; text-align: right; padding: 0 25px; } .price del { float: right; width: 50%; }
20.170 руб 19.162 руб

Python. Сортировка по алфавиту списка словарей

Имеется список словарей следующего содержания.
guys_json = [ { "id": 3, "full_name": "Ффффф", "post": "Водитель", "image": "xxx.jpg"}, { "id": 20, "full_name": "Рррр", "post": "Повар", "image": "yyy.jpg"}, { "id": 11, "full_name": "Аааа", "post": "Директор", "image": "tre.jpg"}, ....]
Необходимо отсортировать его в алфавитном порядке средствами python по полю 'full name' и раскидать объекты в категории по буквам кириллического алфавита ("А", "Б"... "Я"). Подскажите, пожалуйста, с какой стороны подойти к решению


Ответ

Данные в вопросе не являются JSON объектом, например, json.loads() выкинет ошибку.
Если интерпертировать данные как исходный код Питона, тогда guys_json (вводящее в заблуждение имя) является обычным списком словарей (никакого отношения к JSON-формату, кроме того что синтаксис похож (как и задумано)).
Легко отсортировать список словарей по значению заданного поля:
list_of_dicts.sort(key=lambda d: d['full_name'])
Уже есть готовая функция, которую можно вместо lambda использовать:
from operator import itemgetter
list_of_dicts.sort(key=itemgetter('full_name'))
Обе вызова сортируют, используя лексикографический порядок, что для не-ASCII символов может быть не то что нужно. См. Поиск упорядоченной подстроки в строке Python

шаблонный класс - друг

Как объявить в такой ситуации A другом B и можно ли использовать одинаковый параметр t?
template class A; template class B { public: friend template class A; // <-- ошибка };


Ответ

Всё ведь просто:
template class A; template class B { public: friend class A; };

Если нужно, чтобы другом были все A, а не только те, что имеют тот же шаблонный параметр, то можно написать так:
template class A; template class B { public: template friend class A; };

Swap переменных xor'ом в одно выражение

Является ли такой способ обмена значений переменных неопределённым поведением?
http://codepad.org/3IFTpgwR
#include
int main(void) { int x = 10, y = 20; x ^= y ^= x ^= y; printf("%d %d", x, y); return 0; }
Здесь есть двукратное присваивание переменной x - является ли оно некорректным?
PS: Вопрос возник из-за того, что другие языки иначе вычисляют эту конструкцию.


Ответ

Да, является. Операция xor-c-присваиванием (^=) не является точкой следования
Многократное присваивание в рамках одной точки следования - UB.
Для обмена переменных в c++ есть std::swap()