2017-12-14 300 views
5

Jest to lista wartości binarnych: zainfekowaniu przekazywania wartości do sąsiednich elementów listy w języku C#

List<bool> myList = new List<bool>(){true, true, false, false, true, false, false, false, true, true, true, false, false}; 

mój algorytm dąży do konwersji dowolnego fałszywą pozycję na true, jeśli są one w sąsiedztwie prawdziwa wartość:

result = {true, true, true, true, true, true, false, true, true, true, true, true, false} 

Moje rozwiązanie działa, jak widać. Można to zrobić za pomocą dwóch różnych pętli, a następnie zip dwie listy:

List<bool> firstList = new List<bool>(); 
List<bool> secondList = new List<bool>(); 
for(int i=0; i<myList.Count()-1; i++){ 
    if(myList[i]==true){ 
    firstList[i]=true; 
    firstList[i+1]=true; 
    } 
} 

for(int i=1; i<myList.Count(); i++){ 
    if(myList[i]==true){ 
    secondList[i]=true; 
    secondList[i-1]=true; 
    } 
} 

List<bool> finalList = firstList.Zip(secondList, (a,b)=>a||b).ToList(); 

Jednak nie wydaje się być najlepszym rozwiązaniem, ponieważ problem wygląda bardzo proste. Jakiś pomysł na zrobienie tego za pomocą jednej pętli lub najlepiej używając linq?

Odpowiedz

6

Oto podejście LINQ

zasadzie ma takie samo zachowanie jak twoje podejście - element jaźni x, poprzedniego lub następnego .ElementAtOrDefault(i - 1).ElementAtOrDefault(i + 1) elementem musi być prawdą.

List<bool> result = myList.Select((x, i) => x || myList.ElementAtOrDefault(i - 1) || myList.ElementAtOrDefault(i + 1)).ToList(); 
+0

dlaczego nie używać agregacji? –

6

Można to zrobić w jednej pętli:

List<bool> result = myList.Select((b, index) => 
        b || 
        (index > 0 && myList[index-1]) || 
        (index < (myList.Count - 1) && myList[index+1])).ToList(); 

ten trwa co b w swoim myList i kontroli (przez index) jeśli ten sam lub wartości adjacting są true. Oczywiście musimy sprawdzić index dla granic list.

+0

@Dziękuję za inteligentne rozwiązanie. wali, ale jeśli nie masz nic przeciwko, przyjmuję rozwiązanie Fubo. Podoba mi się sposób, w jaki użył metody ElementAtOrDefault. –

+2

@AryanFirouzyan To dobrze, zaakceptuj to, które pasuje do twoich potrzeb. "ElementAtOrDefault()" jest rzeczywiście ładniejszy. –

1

Nie sądzę, jest to szczególnie czytelny, ale:

var indexesToChange = 
    Enumerable.Range(0, myList.Count) 
    .Where(n => myList[n] 
     || (n-1 >= 0 && myList[n-1]) 
     || (n+1 < myList.Count && myList[n+1])) 
    .ToList(); 

foreach (var i in indexesToChange) 
{ 
    myList[i] = true; 
} 

ten zaktualizuje starą listę. Możesz skopiować na nową listę w pętli foreach, jeśli nie chcesz zmieniać starej.