Если вы пытаетесь получить доступ к «user.name», но тогда это происходит:
Uncaught TypeError: Cannot read property 'name' of undefined
Не бойтесь. Вы можете решить это, используя & amp; & amp; оператор в задании или часто называемый сторожевым оператором, так как он «защищает» от неопределенной ошибки.
Вот несколько примеров, которые вы можете найти нечетными, но продолжайте читать, как объясняется позже.
var user = undefined;
var username = user && user.username;
// no error, "username" assigned value of "user" which is undefined
user = { username: 'Johnny' };
username = user && user.username;
// no error, "username" assigned 'Johnny'
user = { };
username = user && user.username;
// no error, "username" assigned value of "username" which is undefined
Объяснение: В режиме охраны каждый термин оценивается слева направо по одному. Если оцениваемое значение является ложным, оценка останавливается и это значение затем назначается. Если последний элемент достигнут, тогда ему присваивается, является ли он ложным.
ложь означает, что это любое из этих значений undefined, false, 0, null, NaN, ''
, а правда просто означает НЕ ложь.
Легкая кнопка для метода Guard
Используйте прекрасный защитный оператор lodash для доступа к вложенным данным следующим образом:
// need to access obj.has.some.very.nested.stuff
var val = _.get(obj, 'has.some.very.nested.stuff');
, поскольку он обрабатывает & amp; & amp; & amp; & amp; материал под капотом, будучи приятным в использовании удобным способом. Исходный код Lodash _.get
Другим полезным странным назначением, которое в практическом использовании, является оператор OR, который обычно используется для таких плагинов:
this.myWidget = this.myWidget || (function() {
// define widget
})();
, который будет назначать только часть кода, если «this.myWidget» является ложным. Это удобно, потому что вы можете объявлять код в любом месте и несколько раз, не заботясь о том, был ли он назначен или нет ранее, зная, что он будет назначен только один раз, поскольку люди, использующие плагин, могут несколько раз объявлять ваш скриптовый тег src несколько раз.
Объяснение: Каждое значение оценивается слева направо, по одному за раз. Если значение является правдивым, оно прекращает оценку и присваивает это значение, в противном случае продолжает движение, если последний элемент достигнут, он присваивается независимо от того, является ли он ложным или нет.
Теперь у вас есть максимальная сила и вы можете делать очень странные вещи, такие как этот очень странный пример использования его в палиндроме.
function palindrome(s,i) {
return (i >= s.length/2) || (s[i] === s[s.length -1 - i]) && palindrome(s, ++i);
}
Подробное объяснение здесь: Проверка палиндрома в Javascript
Счастливое кодирование.
Нужно указать, что split()
сомнительный подход для парсинга файлов CSV в случае, если Вы сталкиваетесь с запятыми в файле, например:
1,"Something, with a comma",2,3
другая вещь я укажу, не зная, как Вы представили, быть осторожным относительно профилирования этого вида низкоуровневой детали. Гранулярность таймера Windows/ПК могла бы сыграть роль, и у Вас могут быть значительные издержки в просто цикличном выполнении, так используйте своего рода значение управления.
Однако split()
создается для обработки регулярных выражений, которые, очевидно, более сложны, чем Вы должны (и неправильный инструмент иметь дело с завершенными запятыми так или иначе). Кроме того, split()
создает много временных объектов.
Поэтому, если Вы хотите ускорить его (и я испытываю затруднения, полагая, что производительность этой части является действительно проблемой) затем Вы хотите сделать это вручную, и Вы хотите снова использовать свои буферные объекты, таким образом, Вы постоянно не создаете объекты и даете работу сборщика "мусора", чтобы сделать в чистке их.
алгоритм для этого относительно прост:
, О, и давать Вам некоторое представление о стоимости regex, был вопрос (Java не, C#, но принцип был тем же), где кто-то хотел заменить каждый энный символ строкой. Я предложил использовать replaceAll()
на Строке. Jon Skeet вручную кодировал цикл. Из любопытства я сравнил эти две версии, и его был порядок величины лучше.
Поэтому, если Вы действительно хотите производительность, пора вручить синтаксический анализ.
Или, еще лучше, используют чужое оптимизированное решение как этот быстрый читатель CSV .
Между прочим, в то время как это относительно Java, он касается производительности регулярных выражений в целом (который универсален), и replaceAll()
по сравнению с кодированным рукой циклом: символ Помещения в Java представляют в виде строки для каждого N символы .
Можно принять ту Строку. Разделение будет близко к оптимальному; т.е. могло быть довольно трудно изменить к лучшему его. Безусловно более легкое решение состоит в том, чтобы проверить, необходимо ли разделить строку вообще. Довольно вероятно, что Вы будете использовать отдельные строки непосредственно. При определении класса StringShim (ссылка на Строку, начните & закончите индекс), Вы сможете разделить Строку на ряд контейнеров вместо этого. Они будут иметь маленький, фиксированный размер и не вызовут строковые копии данных.
Парсинг CSV на самом деле жестоко сложен для разбираний, я использовал классы на основе обертывания текстового драйвера ODBC тот и только время, я должен был сделать это.
решение ODBC, рекомендуемое выше взглядов на первый взгляд, чтобы быть в основном тем же подходом.
я полностью рекомендую провести некоторое исследование на CSV, анализирующем, прежде чем Вы станете слишком далекими вниз путь это (слишком распространенные) работы nearly-but-not-quite. Вещь Excel только дважды заключающих в кавычки строк, что потребность это - один из самых хитрых для контакта с, по моему опыту.
Некоторый очень полный анализ Строки. Разрез () по сравнению с Regex и другими методами.
Мы говорим сбережения мс по очень большим строкам все же.
Реализация BCL строки. Разделение на самом деле довольно быстро, я сделал некоторое тестирование, здесь пытаясь формовать его, и это не легко.
, Но существует одна вещь, которую можно сделать, и это должно реализовать это как генератор:
public static IEnumerable<string> GetSplit( this string s, char c )
{
int l = s.Length;
int i = 0, j = s.IndexOf( c, 0, l );
if ( j == -1 ) // No such substring
{
yield return s; // Return original and break
yield break;
}
while ( j != -1 )
{
if ( j - i > 0 ) // Non empty?
{
yield return s.Substring( i, j - i ); // Return non-empty match
}
i = j + 1;
j = s.IndexOf( c, i, l - i );
}
if ( i < l ) // Has remainder?
{
yield return s.Substring( i, l - i ); // Return remaining trail
}
}
вышеупомянутый метод не обязательно быстрее, чем строка. Разделение для маленьких строк, но это возвращает результаты, поскольку это находит их, это - питание отложенных вычислений. Если Вы имеете длинные линии или должны сохранить память, это - способ пойти.
вышеупомянутый метод ограничен работой IndexOf и Подстроки, которая делает слишком много индекса проверки диапазона, и быть быстрее необходимо оптимизировать далеко их и реализовать собственные вспомогательные методы. Можно победить строку. Производительность разделения, но это собирается брать взламывание интервала секача. Можно прочитать мое сообщение об этом здесь .
Вы могли бы думать, что существует оптимизация, которая будет иметься, но действительность будет, Вы заплатите за них в другом месте.
Вы могли, например, сделать разделение 'сами' и идти через все символы и обработать каждый столбец, поскольку Вы встречаетесь с ним, но Вы скопировали бы все части строки в конечном счете во всяком случае.
Одна из оптимизации, которую мы могли сделать в C или C++, например, является заменой все разделители с '\0' символами, и сохраните указатели на запуск столбца. Затем мы не должны были бы копировать все строковые данные только для получения до части его. Но это, которое Вы не можете сделать в C#, и при этом Вы не хотели бы.
, Если существует большая разница между числом столбцов, которые находятся в источнике и числе столбцов, в которых Вы нуждаетесь, обходя строку вручную, может привести к некоторому преимуществу. Но то преимущество стоило бы Вам времени, чтобы разработать его и поддержать его.
мне сказали, что 90% процессорного времени потрачены в 10% кода. Существуют изменения к этой "истине". По-моему, расходы 66% Вашего времени в Разделении не состоят в том, что плохо при обработке CSV вещь, которую должно сделать приложение.
Dave
Основная проблема (?) со Строкой. Разделение - то, что это является общим, в котором это обслуживает много потребностей.
, Если Вы знаете больше о своих данных, чем Разделение, был бы, это может сделать улучшение для создания собственного.
, Например, если:
, Если какой-либо из них верен, Вы могли бы видеть улучшение путем записи собственной более определенной версии Строки. Разделение.
Однако первый вопрос, который необходимо задать, состоит в том, является ли это на самом деле проблемой, которую стоит решить. Время потрачено, чтобы считать и импортировать файл так долго, что Вы на самом деле чувствуете, что это - хорошее использование Вашего времени? В противном случае затем я оставил бы его в покое.
второй вопрос состоит в том почему Строка. Разделение использует так много времени по сравнению с остальной частью Вашего кода. Если ответ - то, что код делает очень мало с данными, то я, вероятно, не обеспокоился бы.
Однако, если, скажем, Вы наполняете данные в базу данных, затем 66% времени Вашего кода, потраченного в Строке. Разделение составляет большую большую проблему.
В зависимости от использования, вы можете ускорить это, используя Pattern.split вместо String.split. Если у вас есть этот код в цикле (что я предполагаю, что вы, вероятно, делаете, поскольку это звучит так, как будто вы анализируете строки из файла) String.split (String regex) будет вызывать Pattern.compile в вашей строке регулярного выражения каждый раз, когда этот оператор цикла выполняет. Чтобы оптимизировать это, Pattern.com скомпилируйте образец один раз вне цикла, а затем используйте Pattern.split, передав строку, которую вы хотите разделить, внутри цикла.
Надеюсь, это поможет