recortar - string c# ejemplos
¿Cómo uso LINQ contiene(cadena[]) en lugar de contiene(cadena) (20)
Tengo una gran pregunta.
Tengo una consulta de linq para decir que simplemente se ve así:
from xx in table
where xx.uid.ToString().Contains(string[])
select xx
Los valores de la matriz de string[]
serían números como (1,45,20,10, etc ...)
el valor predeterminado para .Contains
es .Contains(string)
.
Necesito que haga esto en su lugar: .Contains(string[])
...
EDITAR: Un usuario sugirió escribir una clase de extensión para la string[]
. Me gustaría aprender cómo, pero ¿alguien dispuesto a orientarme en la dirección correcta?
EDITAR: El uid también sería un número. Es por eso que se convierte en una cadena.
Ayuda a alguien?
Creo que también podrías hacer algo como esto.
from xx in table
where (from yy in string[]
select yy).Contains(xx.uid.ToString())
select xx
Entonces, ¿estoy asumiendo correctamente que uid es un identificador único (Guid)? ¿Es solo un ejemplo de un posible escenario o realmente estás tratando de encontrar un guid que coincida con una serie de cadenas?
Si esto es cierto, es posible que desee replantearse todo este enfoque, esto parece una muy mala idea. Probablemente deberías tratar de hacer coincidir un Guid con un Guid
Guid id = new Guid(uid);
var query = from xx in table
where xx.uid == id
select xx;
Honestamente, no puedo imaginar un escenario en el que coincida con una matriz de cadenas que utilice "contiene" al contenido de un Guid sería una buena idea. Por un lado, Contains () no garantizará el orden de los números en el Guid, por lo que podría combinar varios elementos. Sin mencionar que comparar guías de esta manera sería mucho más lento que solo hacerlo directamente.
Este es un ejemplo de una forma de escribir un método de extensión (nota: no usaría esto para matrices muy grandes, otra estructura de datos sería más apropiada ...):
namespace StringExtensionMethods
{
public static class StringExtension
{
public static bool Contains(this string[] stringarray, string pat)
{
bool result = false;
foreach (string s in stringarray)
{
if (s == pat)
{
result = true;
break;
}
}
return result;
}
}
}
Qué tal si:
from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx
Debería escribirlo al revés, verificando que su lista de identificación de usuario privilegiada contenga el ID en esa fila de la tabla:
string[] search = new string[] { "2", "3" };
var result = from x in xx where search.Contains(x.uid.ToString()) select x;
LINQ se comporta bastante brillante aquí y lo convierte en una buena declaración SQL:
sp_executesql N''SELECT [t0].[uid]
FROM [dbo].[xx] AS [t0]
WHERE (CONVERT(NVarChar,[t0].[uid]))
IN (@p0, @p1)'',N''@p0 nvarchar(1),
@p1 nvarchar(1)'',@p0=N''2'',@p1=N''3''
que básicamente incorpora el contenido de la matriz ''búsqueda'' en la consulta sql, y lo filtra con la palabra clave ''IN'' en SQL.
Me las arreglé para encontrar una solución, pero no una gran, ya que requiere el uso de AsEnumerable () que va a devolver todos los resultados de la base de datos, afortunadamente solo tengo 1k registros en la tabla, por lo que no es realmente notable, pero aquí va .
var users = from u in (from u in ctx.Users
where u.Mod_Status != "D"
select u).AsEnumerable()
where ar.All(n => u.FullName.IndexOf(n,
StringComparison.InvariantCultureIgnoreCase) >= 0)
select u;
Mi publicación original sigue:
¿Cómo haces el reverso? Quiero hacer algo como lo siguiente en el marco de la entidad.
string[] search = new string[] { "John", "Doe" }; var users = from u in ctx.Users from s in search where u.FullName.Contains(s) select u;
Lo que quiero es encontrar todos los usuarios donde su nombre completo contenga todos los elementos en `búsqueda ''. Lo intenté de diferentes maneras, todas las cuales no me han funcionado.
También intenté
var users = from u in ctx.Users select u; foreach (string s in search) { users = users.Where(u => u.FullName.Contains(s)); }
Esta versión solo encuentra aquellas que contienen el último elemento en la matriz de búsqueda.
La mejor solución que encontré fue seguir adelante y crear una función con valores de tabla en SQL que produzca los resultados, tales como:
CREATE function [dbo].[getMatches](@textStr nvarchar(50)) returns @MatchTbl table(
Fullname nvarchar(50) null,
ID nvarchar(50) null
)
as begin
declare @SearchStr nvarchar(50);
set @SearchStr = ''%'' + @textStr + ''%'';
insert into @MatchTbl
select (LName + '', '' + FName + '' '' + MName) AS FullName, ID = ID from employees where LName like @SearchStr;
return;
end
GO
select * from dbo.getMatches(''j'')
Luego, simplemente arrastre la función a su diseñador LINQ.dbml y llámela como lo hace con sus otros objetos. El LINQ incluso conoce las columnas de su función almacenada. Lo digo así:
Dim db As New NobleLINQ
Dim LNameSearch As String = txt_searchLName.Text
Dim hlink As HyperLink
For Each ee In db.getMatches(LNameSearch)
hlink = New HyperLink With {.Text = ee.Fullname & "<br />", .NavigateUrl = "?ID=" & ee.ID}
pnl_results.Controls.Add(hlink)
Next
Increíblemente simple y realmente aprovecha el poder de SQL y LINQ en la aplicación ... ¡y puedes, por supuesto, generar cualquier función de tabla que quieras para los mismos efectos!
Si realmente desea replicar Contiene , pero para una matriz, aquí hay un método de extensión y un código de muestra para su uso:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ContainsAnyThingy
{
class Program
{
static void Main(string[] args)
{
string testValue = "123345789";
//will print true
Console.WriteLine(testValue.ContainsAny("123", "987", "554"));
//but so will this also print true
Console.WriteLine(testValue.ContainsAny("1", "987", "554"));
Console.ReadKey();
}
}
public static class StringExtensions
{
public static bool ContainsAny(this string str, params string[] values)
{
if (!string.IsNullOrEmpty(str) || values.Length > 0)
{
foreach (string value in values)
{
if(str.Contains(value))
return true;
}
}
return false;
}
}
}
Creo que lo que realmente quieres hacer es: imaginemos que tienes dos bases de datos y tienen una tabla de productos en común Y quieres seleccionar productos de la tabla "A" que el ID tiene en común con la "B"
usar el método contiene sería demasiado complicado para hacer esto, lo que estamos haciendo es una intersección, y hay un método llamado intersección para eso
un ejemplo de msdn: http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#intersect1
int [] números = (0, 2, 4, 5, 6, 8, 9); int [] númerosB = (1, 3, 5, 7, 8); var = números de Números comunesA.Intersect (númerosB);
Creo que lo que necesitas se resuelve fácilmente con la intersección
Prueba lo siguiente.
string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));
O si ya tiene los datos en una lista y prefiere el otro formato Linq :)
List<string> uids = new List<string>(){"1", "45", "20", "10"};
List<user> table = GetDataFromSomewhere();
List<user> newTable = table.Where(xx => uids.Contains(xx.uid)).ToList();
LINQ en .NET 4.0 tiene otra opción para ti; el método .Any ();
string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);
Verifique este método de extensión:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ContainsAnyProgram
{
class Program
{
static void Main(string[] args)
{
const string iphoneAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like...";
var majorAgents = new[] { "iPhone", "Android", "iPad" };
var minorAgents = new[] { "Blackberry", "Windows Phone" };
// true
Console.WriteLine(iphoneAgent.ContainsAny(majorAgents));
// false
Console.WriteLine(iphoneAgent.ContainsAny(minorAgents));
Console.ReadKey();
}
}
public static class StringExtensions
{
/// <summary>
/// Replicates Contains but for an array
/// </summary>
/// <param name="str">The string.</param>
/// <param name="values">The values.</param>
/// <returns></returns>
public static bool ContainsAny(this string str, params string[] values)
{
if (!string.IsNullOrEmpty(str) && values.Length > 0)
return values.Any(str.Contains);
return false;
}
}
}
from xx in table
where xx.uid.Split('','').Contains(string value )
select xx
string[] stringArray = {1,45,20,10};
from xx in table
where stringArray.Contains(xx.uid.ToString())
select xx
Esta es una respuesta tardía, pero creo que todavía es útil .
Creé el paquete nuget NinjaNye.SearchExtension que puede ayudar a resolver este mismo problema .:
string[] terms = new[]{"search", "term", "collection"};
var result = context.Table.Search(terms, x => x.Name);
También puede buscar múltiples propiedades de cadenas
var result = context.Table.Search(terms, x => x.Name, p.Description);
O realice un RankedSearch
que devuelve IQueryable<IRanked<T>>
que simplemente incluye una propiedad que muestra cuántas veces aparecieron los términos de búsqueda:
//Perform search and rank results by the most hits
var result = context.Table.RankedSearch(terms, x => x.Name, x.Description)
.OrderByDescending(r = r.Hits);
Hay una guía más extensa en la página de GitHub de los proyectos: https://github.com/ninjanye/SearchExtensions
Espero que esto ayude a los futuros visitantes
Método de extensión Linq. Funcionará con cualquier objeto IEnumerable:
public static bool ContainsAny<T>(this IEnumerable<T> Collection, IEnumerable<T> Values)
{
return Collection.Any(x=> Values.Contains(x));
}
Uso:
string[] Array1 = {"1", "2"};
string[] Array2 = {"2", "4"};
bool Array2ItemsInArray1 = List1.ContainsAny(List2);
spoulson lo tiene casi correcto, pero primero debe crear una List<string>
desde la string[]
. En realidad, una List<int>
sería mejor si uid también es int
. List<T>
admite Contains()
. Hacer uid.ToString().Contains(string[])
implicaría que el uid como una cadena contiene todos los valores de la matriz como una subcadena ??? Incluso si escribiste el método de extensión, el sentido sería incorrecto.
[EDITAR]
A menos que lo hayas cambiado y lo hayas escrito para la string[]
como demuestra Mitch Wheat, entonces solo podrás saltearte el paso de conversión.
[ENDEDIT]
Esto es lo que desea, si no hace el método de extensión (a menos que ya tenga la colección de fluidos potenciales como elementos), simplemente use List<int>()
lugar). Esto utiliza la sintaxis del método encadenado, que creo que es más limpio, y realiza la conversión a int para garantizar que la consulta se pueda usar con más proveedores.
var uids = arrayofuids.Select(id => int.Parse(id)).ToList();
var selected = table.Where(t => uids.Contains(t.uid));
Tratar:
var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;
Dim stringArray() = {"Pink Floyd", "AC/DC"}
Dim inSQL = From alb In albums Where stringArray.Contains(alb.Field(Of String)("Artiste").ToString())
Select New With
{
.Album = alb.Field(Of String)("Album"),
.Annee = StrReverse(alb.Field(Of Integer)("Annee").ToString())
}