Я попробовал некоторые способы , а затем решил заполнить список вручную и выполнить простую проверку JS. И в конце пользователь должен подтвердить. Потому что некоторые проверки дали ложный положительный или отрицательный.
var isMobile = false;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Opera Mobile|Kindle|Windows Phone|PSP|AvantGo|Atomic Web Browser|Blazer|Chrome Mobile|Dolphin|Dolfin|Doris|GO Browser|Jasmine|MicroB|Mobile Firefox|Mobile Safari|Mobile Silk|Motorola Internet Browser|NetFront|NineSky|Nokia Web Browser|Obigo|Openwave Mobile Browser|Palm Pre web browser|Polaris|PS Vita browser|Puffin|QQbrowser|SEMC Browser|Skyfire|Tear|TeaShark|UC Browser|uZard Web|wOSBrowser|Yandex.Browser mobile/i.test(navigator.userAgent) && confirm('Are you on a mobile device?')) isMobile = true;
Теперь, если вы хотите использовать jQuery для установки CSS, вы можете сделать следующее:
$(document).ready(function() {
if (isMobile) $('link[type="text/css"]').attr('href', '/mobile.css');
});
Поскольку границы между мобильными и стационарными устройствами становятся свободными, а мобильные браузеры уже мощные Проверка ширины и подтверждение пользователя, вероятно, будут наилучшими для будущего (при условии, что ширина в некоторых случаях все еще будет важна). Потому что прикосновения уже превращаются в взлеты и падения мышью.
А что касается подвижной подвижности, я предлагаю вам подумать над идеей Йоава Барни :
if(typeof window.orientation !== 'undefined'){...}
.
Похоже, вы действительно хотите «заархивировать» данные вместе (а не объединить), то есть сопоставить попарно; это верно? Если это так, просто:
var qry = from row in title.Zip(user, (t, u) => new { Title = t, User = u })
where !string.IsNullOrEmpty(row.User)
select row.Title + ":" + row.User;
foreach (string s in qry) Console.WriteLine(s);
с помощью операции Zip
из здесь :
// http://blogs.msdn.com/ericlippert/archive/2009/05/07/zip-me-up.aspx
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>
(this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
if (first == null) throw new ArgumentNullException("first");
if (second == null) throw new ArgumentNullException("second");
if (resultSelector == null) throw new ArgumentNullException("resultSelector");
return ZipIterator(first, second, resultSelector);
}
private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>
(IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
using (IEnumerator<TSecond> e2 = second.GetEnumerator())
while (e1.MoveNext() && e2.MoveNext())
yield return resultSelector(e1.Current, e2.Current);
}
Для начала вам понадобится оператор Zip
, чтобы соединить два массива вместе. Вот сокращенная версия кода из блога Эрика Липперта (без проверки ошибок в этой версии, только для краткости):
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>
(this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
using (IEnumerator<TSecond> e2 = second.GetEnumerator())
while (e1.MoveNext() && e2.MoveNext())
yield return resultSelector(e1.Current, e2.Current);
}
Обратите внимание, что Zip
будет в стандартных библиотеках для. NET 4.0.
Затем вам нужно просто применить фильтр и проекцию. Таким образом, мы получим:
var results = title.Zip(user, (Title, User) => new { Title, User })
.Where(x => x.Title != "")
.Select(x => x.Title + ":" + x.User);
В качестве еще одного дополнения к предыдущим ответам Zip обычно определяется и используется в сочетании с типом Tuple
. Это избавляет пользователя от необходимости предоставлять функцию resultSelector
.
public class Tuple<TItem1, TItem2> // other definitions for higher arity
{
public TItem1 Item1 { get; private set; }
public TItem2 Item2 { get; private set; }
public Tuple(TItem1 item1, TItem2 item2)
{
Item1 = item1;
Item2 = item2;
}
}
И, следовательно:
public static IEnumerable<Tuple<TFirst, TSecond>> Zip<TFirst, TSecond>
(this IEnumerable<TFirst> first, IEnumerable<TSecond> second)
{
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
using (IEnumerator<TSecond> e2 = second.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext())
yield return new Tuple<TFirst, TSecond>(e1.Current, e2.Current);
}
}
Я считаю, что это ближе к тому, что будет в CLR 4.0 (хотя он может иметь и более гибкий вариант) .
В дополнение к уже опубликованным ответам, вот решение без использования метода Zip. Это предполагает, что оба массива имеют одинаковую длину.
var pairs = from idx in Enumerable.Range(0, title.Length)
let pair = new {Title = title[idx], User = user[idx]}
where !String.IsNullOrEmpty(pair.User)
select String.Format("{0}:{1}", pair.Title, pair.User);