Страницы

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

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

Появление элемента после длительного нажатия на блок

Здравствуйте! Имеется список приложений, на мобильных устройствах предусмотрено появление кнопки при длительном нажатии любого из пунктов списка. До этого с версткой подобных элементов не сталкивался, прошу подсказать как такие вещи реализуются.


Ответ

$(document).ready(function(){ var shows = 0; $('#longClick').mousedown(function(){ shows = setTimeout(function(){ $('#shower').show(); }, 2000); }); $('#longClick').mouseup(function(){ clearTimeout(shows); }); $('*').not($('#shower')).mousedown(function(){ $('#shower').hide(); }); });

Click me 2 second
Click for close
Click for close

Анонимный интерфейс c#

Есть интерфейс
intefrace IMy { void say(String msg); }
Есть класс
class My { IMy iMy; public My() { iMy = (str) = > Console.WriteLine(str); //ошибка iMy.say("Text"); } }
На строке с //ошибка мне пишет
Cannot convert lambda expression to type IMy, because it is not a delegate type
Что мне надо изменить в коде, чтобы я мог инициализировать переменную iMy моим способом?
P.S. сам пишу на java, и там такая конструкция работает. Какая аналогичная конструкция в c#?


Ответ

Судя по примеру использования вместо интерфейса в данном случае можно использовать делегат Action, например так
class My { Action iMy; public My() { iMy = (str) => Console.WriteLine(str); //ок iMy("Text"); } }

Поиск в JSON строке значения

Мне нужно получить значение из динамичного JSON. Он огромен , поэтому приводить его полностью не имеет смысла. Меня интересует значения тиража, как мне туда добраться максимально изящно?
По логике мне надо найти слово Тираж в строке и перейти в соседнюю ячейку и получить значение.


Ответ

Воспользуйтесь готовыми парсерами. Читать JSON поиском или регулярными выражениями - не очень хорошая идея. Например, свойство Value не обязано идти до свойства Name, оно может идти и после него. Смысл JSON при этом не изменится, а отловить все такие случаи при поиске будет тяжело.
Json.NET поддерживает такую вещь, как запросы JSONPath
var json = @"{ ""Editions"": {}, ""ItemType"": 5, ""Capabilities"": { ""Capabilities"": [ { ""Name"": ""Тираж"", ""Value"": ""20000"", ""AdditionalProperties"": {} }, { ""Name"": ""aaaa"", ""Value"": ""bbb"", ""AdditionalProperties"": {} } ] } }";
var obj = JObject.Parse(json); var value = (string)obj.SelectToken("$.Capabilities.Capabilities[?(@.Name == 'Тираж')].Value");
Если JSON действительно огромный и десериализовать целиком его накладно по памяти, то придется воспользоваться JsonTextReader, десереализуя только небольшие части файла (код приблизительный, без проверок):
string value = null; using (var reader = new JsonTextReader(new StringReader(json))) { // читаем json, пока не придем в объект Capabilities while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "Capabilities") { break; } }
reader.Read();
// каждый объект из массива десериализуем в JObject while (reader.Read()) { if (reader.TokenType == JsonToken.StartObject) { var obj = JObject.Load(reader); if ((string)obj["Name"] == "Тираж") { value = (string)obj["Value"]; break; } } } }

Аналог функции Swap

Есть ли в С# аналог функции Delphi Swap() ? Верно ли я понимаю, что функция swap меняет местами 2 байта ?


Ответ

В комментариях подсказали, где подсмотреть готовое решение:
Для данных типа ushort:
private ushort Swap(ushort number) { var hi = (byte)(number >> 8); var lo = (byte)(number & 0xff); return (ushort)((lo << 8) | hi); }
Для данных типа Int:
int SwapInt(int number) { var hi = (byte)(number >> 24); var lo = (byte)(number & 0xff); return ((number & 0xffff00) | (lo << 24) | hi); }

Как узнать является ли тип перечислением?

Можно ли как-нибудь проверить, является ли тип перечислением, т.е. enum или enum class?


Ответ

#include #include
class A {}; enum E {}; enum class Ec : int {};
int main() { std::cout << std::boolalpha; std::cout << std::is_enum::value << '
'; std::cout << std::is_enum::value << '
'; std::cout << std::is_enum::value << '
'; std::cout << std::is_enum::value << '
'; }
Ну, или
std::cout << std::is_enum
() << '
'; std::cout << std::is_enum() << '
'; std::cout << std::is_enum() << '
'; std::cout << std::is_enum() << '
';

Ошибка сборки: Cannot find -lGL

При попытке сборки проекта Qt Widgets выдает вот такую ошибку:
g++ -Wl,-rpath,/home/keyreal/Qt/5.7/gcc_64/lib -o untitled3 main.o mainwindow.o moc_mainwindow.o -L/home/keyreal/Qt/5.7/gcc_64/lib -lQt5Widgets -L/usr/lib64 -lQt5Gui -lQt5Core -lGL -lpthread /usr/bin/ld: cannot find -lGL collect2: error: ld returned 1 exit status make: *** [untitled3] Ошибка 1 22:41:13: Процесс «/usr/bin/make» завершился с кодом 2. Ошибка при сборке/установке проекта untitled3 (комплект: Desktop Qt 5.7.0 GCC 64bit)`
Ошибку выдает только если создается проект Qt Widgets, с консольным приложением вроде всё работает. Проект создается пустой абсолютно, т.е. туда ничего не внесено и никаких дополнительных классов не используется
ОС - Ubuntu 14.04 с XFCE.


Ответ

Установите пакет libgl1-mesa-dev
Добавлено
Разумеется, нет возможности гарантировать, что на неких специфичных убунтах с нестандартным набором установленных пакетов, обозначенный пакет не затребует что-либо удалить. Речь о стандартной поставке Ubuntu с Gnome, начиная с 14.04 и по 16.04 включительно. Подозреваю, что и для более ранних версий, а также для версий с XFCE ситуация не изменится (самолично не проверял, не пользуюсь этим DE).
Предоставляемые пакетом файлы:
/. /usr /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/libGL.so /usr/lib/x86_64-linux-gnu/libglapi.so /usr/lib/x86_64-linux-gnu/mesa /usr/lib/x86_64-linux-gnu/mesa/libGL.so /usr/lib/x86_64-linux-gnu/pkgconfig /usr/lib/x86_64-linux-gnu/pkgconfig/gl.pc /usr/share /usr/share/bug /usr/share/bug/libgl1-mesa-dev /usr/share/bug/libgl1-mesa-dev/control /usr/share/bug/libgl1-mesa-dev/script /usr/share/doc /usr/share/doc/libgl1-mesa-dev /usr/share/doc/libgl1-mesa-dev/changelog.Debian.gz /usr/share/doc/libgl1-mesa-dev/copyright
Как видно, пакет содержит искомую библиотеку: libGL.so
При установке на систему Ubuntu 16.04 Gnome ничего не запрашивает снести.

Зачем нужны переменные таблицы и когда их лучше использовать?

В MS SQL есть переменные таблицы.
В некоторых случаях я замечал, что темповые таблицы работают быстрее, за счет того, что в них используется параллелизм в отличии от переменных.
Единственный минус темповых таблиц, как я думаю - это то, что их нужно проверять и дропать если они есть перед создание.
Так вот, для каких целей они могут понадобится, когда есть темповые таблицы и когда их лучше использовать?


Ответ

Единственный минус темповых таблиц, как я думаю - это то, что их нужно проверять и дропать если они есть перед созданием.
На мой взгляд это проблема только при @@nestlevel равном 0, да и то не всегда (например, если открываем соединение, создаём #-таблицу, что-то делаем и закрываем соединение, то в проверке нет необходимости). Внутри модуля (триггера или процедуры), если нужно создать #table, то можно не проверять и не дропать (это может быть и вредным), даже если на внешнем уровне уже была создана #table с тем же самым именем.
Т.е., например, есть процедура
create procedure SomeProc as begin set nocount on;
create table #table (id int); insert into #table values (1), (2);
select * from #table; end GO
Можно создать #table и вызвать SomeProc
create table #table (value float); insert into #table values (100.0), (200.0); exec SomeProc; -- #table внутри SomeProc - это другая #table select * from #table; drop table #table; GO
при этом #table, созданная снаружи SomeProc, и #table, созданная внутри SomeProc - разные и между собой не интерферируют. Если внутри SomeProc перед create table #table поставить проверку существования #table и drop table #table, то уничтожится таблица, созданная на внешнем уровне, и код, следующий за процедурой, сломается.
Так вот, для каких целей они могут понадобиться, когда есть темповые таблицы
При выборе между @table и #table, как мне кажется, следует исходить из свойств и особенностей этих двух типов таблиц. У @-таблиц по сравнению с #-таблицами довольно много ограничений, много общего, и есть особенности присущие только @-таблицам.
Подробно этот вопрос освещён здесь и здесь. Ниже некоторое обобщение информации по этим двум ссылкам (неполное).

Хранилище: Вопреки расхожему представлению о том, что @-таблицы хранятся в оперативной памяти, а #-таблицы - в tempdb, разницы в этом плане между ними на самом деле нет. И те и другие хранятся в tempdb, и, также, и те и другие одинаково буферизуются.
Область видимости: #-таблицы доступны на том уровне, на котором они создаются и на вложенных (@@nestlevel больше текущего). @-таблицы доступны только в рамках того batch-а или модуля, в котором они объявляются (впрочем, типированные @-таблицы на вложенные уровни можно передавать параметром).
Жизненный цикл: @-таблицы создаются неявно в самом начале того батча, в котором они объявлены, перед выполнением всех остальных команд (а если это модуль, то перед началом выполнения модуля), независимо от того, будет ли достигнута в процессе исполнения соответствующая declare инструкция, или нет. Вот такой код, например, вполне работает:
if 1 != 0 declare @table1 table (id int); else declare @table2 table (name varchar(20));
select * from @table1; select * from @table2; GO
уничтожаются @-таблицы после выхода из соответствующего батча или модуля, в котором они объявлены.
#-таблицы создаются тогда, когда встречается соответствующая create table инструкция; уничтожаются тогда, когда встречается соответствующая drop table инструкция, либо при уменьшении уровня вложенности (выхода из модуля или exec инструкции), или закрытии соединения (если #-таблица была создана на нулевом уровне вложенности).
Использование в функциях и процедурах: #-таблицы нельзя создавать в пользовательских скалярных и multi-line табличных функциях, @-таблицы - можно. Типированные @-таблицы можно передавать в функции и процедуры параметром. #-таблицы нельзя передавать в функции (хотя можно получить к ним доступ косвенно - через синоним). В процедурах #-таблицы, созданные на внешнем уровне - доступны.
Сollation: При создании @-таблиц столбцы строковых типов (если они присутствуют) наследуют collation от текущей БД. При создании #-таблиц столбцы строковых типов наследуют collation от tempdb, либо от текущей БД, если та является автономной (contained).
Индексы/ключи: До SqlServer 2014 на @-таблицах можно было задавать только уникальные ключи
declare @table table ( id int primary key, uid uniqueidentifier unique )
В SqlServer 2014 с добавлением inline-синтаксиса для создания индексов стало возможным добавлять неуникальные индексы
declare @table table ( value varchar(20), index ix_1 (value) )
В SqlServer 2016 стало возможным добавление уникальных и отфильтрованных индексов
declare @table table ( id int, value varchar(20), index ix_1 unique (value), index ix_2 (id) where value is NULL )
Индексы с include, а также специальные виды индексов на @-таблицах на настоящий момент не поддерживаются.
Компиляция запросов: Оптимизатор запросов во многих случаях полагает, что @-таблица содержит одну единственную строку. На @-таблицах не поддерживаются статистики по столбцам.
Транзакции: Изменение содержимого @-таблиц всегда происходит в системной транзакции, поэтому они нечувствительны к rollback
declare @table table (value int); create table #table (value int); begin tran; insert into @table values (1); insert into #table values (2); rollback; select * from @table; select * from #table; drop table #table;
Параллелизм: Запросы, меняющие содержимое @table (insert/update/delete) не могут использовать параллелизм. Запросы читающие из @table (select) могут иметь параллельный план.
Табличные подсказки: На @-таблицах нельзя использовать табличные подсказки (table hints), на #-таблицы такое ограничение не накладывается.
Другое: @-таблицу нельзя создать при помощи select * into @table from .... Для @-таблиц недоступны truncate table, alter table, create index