从连续出现的所有重复开始

时间:2017-09-15 02:19:02

标签: c# sql linq

有没有办法翻译以下查询

select word
from string1 
where Left(word, 1) in (
     select Left(word, 1) as firstInitial 
     from string1 
     group by Left(word , 1)
     having count(*) > 1
)
进入LINQ所以当你运行它时“在Kim继续踢的时候,我非常喜欢吃Dunkin甜甜圈”它会产生类似的东西

(miss,Match,Match,Match,miss,miss,miss,Match,Match,miss,Match,Match)

2 个答案:

答案 0 :(得分:1)

以下解决方案显示了一种可能的方法。要使用此功能,请务必将MoreLINQ NuGet package添加到项目中。

using System;
using System.Linq;
using MoreLinq;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var input = "While Kim kept kicking I ate my Dunkin donut with great gusto";

            var value = input.Split(' ');

            var lagged = value.Lag(1, (current, previous) => new { current = current?.ToLowerInvariant(), previous = previous?.ToLowerInvariant() });
            var leaded = value.Lead(1, (current, next) => new { next = next?.ToLowerInvariant() });

            var results = lagged.Zip(leaded, (x, y) => x.current?.FirstOrDefault() == x.previous?.FirstOrDefault() ||
                                                       x.current?.FirstOrDefault() == y.next?.FirstOrDefault());

            Console.WriteLine(string.Join(",", results));
            Console.ReadLine();
        }
    }
}

基本上,代码将字符串拆分为多个单词,然后查看每个单词(current)和单词(previous)之前和之后(next)。然后,它会将current的第一个字母与previousnext的第一个字母进行比较。

如果您想返回1 / 0而不是true / false,请更改此行代码:

var results = lagged.Zip(leaded, (x, y) => (x.current?.FirstOrDefault() == x.previous?.FirstOrDefault() ||
                                            x.current?.FirstOrDefault() == y.next?.FirstOrDefault()) ? 1 : 0);

答案 1 :(得分:1)

这个解决方案不会像几行一样简单,但我可以试试:

首先,最简单但不那么优雅的for循环方法:

var words = string1.Split(' ').ToList();
string[] results = new string[words.Count];    //edited: can use .Count instead of .Count()
for (int i = 0; i < words.Count; i++)
{
    if (i == words.Count - 1)
        results[i] = char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss";
    else if (i == 0)
        results[i] = char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss";
    else
    {
        bool leftMatch = char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]);
        bool rightMatch = char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0]);
        results[i] = (leftMatch || rightMatch) ? "Match" : "miss";
    }
}

这样做是通过每个元素,如果左边或右边的单词具有相同的初始字符,它是&#34;匹配&#34;否则它是&#34; miss&#34;。对于第一个和最后一个词,它只需要检查一个邻居而不是2。

使用Enumerable.Range Method (Int32, Int32) LINQ以及?: Operator,可以简化为几行:

var words = string1.Split(' ').ToList();
var results = Enumerable.Range(0, words.Count).Select(i => i == words.Count - 1 ?
        char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss" :
        i == 0 ?
        char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0]) ? "Match" : "miss" :
        (char.ToLower(words[i - 1][0]) == char.ToLower(words[i][0]) || char.ToLower(words[i + 1][0]) == char.ToLower(words[i][0])) ? "Match" : "miss" ).ToList();

最后的ToList()是可选的,如果您愿意,可以转换ToArray()