J'ai la liste suivante -
public List<edgeData> RemoveLinks(List<edgeData>() edgeList, int linkCount)
{
var updatedEdgeData = new List<edgeData>();
// logic
return updatedEdgeData;
}
Je souhaite supprimer une entrée edgeData de edgeList lorsque la source collectivement est inférieur ou égal à linkCount.
Par exemple, construisez mon edgeData -
var newEdge = new edgeData(); newEdge.source = "James"; newEdge.target = 1; edgeList.Add(newEdge); var newEdge = new edgeData(); newEdge.source = "Greg"; newEdge.target = 2; edgeList.Add(newEdge); var newEdge = new edgeData(); newEdge.source = "James"; newEdge.target = 3; edgeList.Add(newEdge);
Puis traitez pour supprimer les entrées qui sont inférieures ou égales à linkCount-
public class edgeData
{
public string source { get; set; }
public string target { get; set; }
}
var edgeList = new List<edgeData>();
var linkCount = 1;
Donc, dans l'exemple, l'entrée contenant "Greg" comme source serait supprimée car il ne s'est produit qu'une seule fois, ce qui est égal à linkCount.
J'ai essayé de faire cela avec une boucle for, mais cela est devenu incroyablement moche assez rapidement et je pense que Linq est la meilleure option, mais comment puis-je y parvenir? p>
3 Réponses :
Vous pouvez faire ce qui suit
edgeList.GroupBy(x=>x.source)
.Where(x=>x.Skip(linkCount).Any())
.SelectMany(x=>x)
.ToList()
Vous devez Grouper par la source et filtrer les groupes qui ont des éléments inférieurs au linkCount code>.
Veuillez également noter que selon OP, edgeData.target est une chaîne, mais votre code l'affiche sous forme de nombre. Espérons que ce soit une faute de frappe.
Mise à jour
Comme l'a souligné Harald, si la taille du groupe est énorme, vous pouvez également utiliser,
edgeList.GroupBy(x=>x.source)
.Where(x=>x.Count()>linkCount)
.SelectMany(x=>x)
.ToList();
Si l'un de vos groupes a un million d'éléments et que linkCount a une valeur de 5, pourquoi Count () all million d'éléments? Utilisez plutôt Skip (5) .Any () .
@HaraldCoppoolse Merci de l'avoir signalé, nous avons mis à jour la réponse
En gros, comptez simplement l'occurrence des noms, puis bouclez sur la liste et supprimez celui que vous n'aimez pas (pas assez de connexions)
Dictionary<string, int> occurrence = new Dictionary<string, int>();
foreach (edgeData edge in edgeList)
{
if (occurrence.ContainsKey(edge.source))
occurrence[edge.source] += 1;
else
occurrence[edge.source] = 1;
}
int counter = 0;
while(counter < edgeList.Count)
{
if (occurrence[edgeList[counter].source] < linkCount)
edgeList.RemoveAt(counter);
else
counter++;
}
Je souhaite supprimer une entrée edgeData de edgeList lorsque la source est collectivement inférieure ou égale à linkCount.
Je pense que vous ne voulez dans votre résultat final que les éléments de votre séquence d'entrée qui ont une valeur de propriété
Sourcequi apparaît plus de fois dans votre séquence quelinkCount.Donc, si
linkCountvaut 5, vous ne voulez conserver ces enregistrements que là où il y a au moins cinq occurrences de cetteSourcedans la séquence d'entrée.Pour cela, nous devons regrouper votre entrée en groupes avec la même valeur pour
Source. Après cela, nous ne conservons que les groupes qui contiennent plus d'éléments quelinkCount:IEnumerable<EdgeData> result = edgeList.GroupBy( edgeItem => edgeItem.Source) // keep only the groups with enough elements: .Where(group => group.Skip(linkCount).Any()) // Ungroup, so we get a neat sequence .SelectMany(group => group);Le résultat de GroupBy est une séquence d'objets où chacun object implémente
IGrouping. Cet objet est en lui-même une séquence deEdgeData, où chaque propriétéSourcea la même valeur. Cette valeur est dans laKeyde l'IGrouping.Après avoir créé les groupes, je ne garde que les groupes qui contiennent plus de linkCount éléments. Je fais cela, en sautant les premiers éléments LinkCount de la séquence que le groupe est, et s'il reste des éléments, alors apparemment le groupe a plus que des éléments linkCount.
Je ne veux pas utiliser Count (), car si votre groupe a un million d'éléments, ce serait une perte de puissance de traitement de compter tous ces éléments, si vous arrêtez de compter après avoir vu qu'il y en a plus que linkCount.
Le résultat du Where est une séquence de
IGroupingPour dégrouper, nous utilisonsSelectMany, ce qui en fait une séquence soignée deEdgeData code> à nouveau.
C'est une réponse excellente et informative avec du temps.
Qu'est-ce que tu as essayé jusque-là? De plus, votre code ne sera pas compilé, vous ne pouvez pas attribuer la valeur
intà la chaîneIl vaut la peine de mentionner votre identifiant unique d'un article de la collection. Je suppose que c'est une propriété
source?edgeList.RemoveAll (edge => when_to_remove);