Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用其他集合替换集合中的项目序列?_C#_Collections_Replace_Sequence - Fatal编程技术网

C# 如何使用其他集合替换集合中的项目序列?

C# 如何使用其他集合替换集合中的项目序列?,c#,collections,replace,sequence,C#,Collections,Replace,Sequence,假设我有一个int数组: var source = new int[] { 1, 2, 3, 4, 5 }; 我想使用以下阵列替换其中的一部分: var fromArray = new int[] { 1, 2 }; var toArray = new int[] { 11, 12 }; 我需要使用上面的数组生成的输出是:11,12,3,4,5 在更高级的场景中,我可能还需要使用多个参数替换源。认为fromArray和toArray来自字典: 我认为它会正常工作 void Repla

假设我有一个int数组:

var source = new int[] { 1, 2, 3, 4, 5 };
我想使用以下阵列替换其中的一部分:

var fromArray = new int[] { 1, 2 };
var toArray = new int[] { 11, 12 };
我需要使用上面的数组生成的输出是:
11,12,3,4,5

在更高级的场景中,我可能还需要使用多个参数替换源。认为
fromArray
toArray
来自
字典


我认为它会正常工作

    void Replace<T>(ref T[] source, IDictionary<T[], T[]> values)
    {
        int start = 0;
        int index = -1;
        foreach (var item in values)
        {
            start = 0;

            while ((index = IndexOfSequence<T>(source, item.Key, start)) >= 0)
            {
                for (int i = index; i < index + item.Key.Length; i++)
                {
                    source[i] = item.Value[i - index];
                }

                start = index + item.Key.Length + 1;
            }
        }
    }

    public int IndexOfSequence<T>(T[] source, T[] sequence, int start)
    {
        int j = -1;

        if (sequence.Length == 0)
            return j;

        for (int i = start; i < source.Length; i++)
        {
            if (source[i].Equals(sequence[0]) && source.Length >= i + sequence.Length)
            {
                for (j = i + 1; j < i + sequence.Length; j++)
                {
                    if (!source[j].Equals(sequence[j - i]))
                        break;
                }

                if (j - i == sequence.Length)
                    return i;
            }
        }

        return -1;
    }
void Replace(参考T[]源代码,IDictionary值)
{
int start=0;
int指数=-1;
foreach(值中的var项)
{
开始=0;
而((index=IndexOfSequence(source,item.Key,start))>=0)
{
for(int i=index;i=i+sequence.Length)
{
对于(j=i+1;j
如果你喜欢林克:)

IEnumerable替换(IEnumerable源、,
(字典值)
{ 
//“values”参数保存我要替换的对。
//如果是索引器,“source”可以是`IList`而不是`IEnumerable
//是必需的,但我更喜欢'IEnumerable'。
IList sourceAsList=源作为IList;
if(sourceAsList==null)
{
sourceAsList=source.ToList();
}
foreach(值中的var kvp)
{
//重复上面同样的事情。
}
} 

如果您需要支持general
IEnumerable
(而不是数组
T[]
),可能类似于:

IEnumerable<T> Replace<T>(IEnumerable<T> source, IEnumerable<T> fromSeq, IEnumerable<T> toSeq)
{
  var dict = fromSeq.Zip(toSeq, (fr, to) => new { Fr = fr, To = to })
    .ToDictionary(a => a.Fr, a => a.To);

  foreach (var s in source)
  {
    T replace;
    if (dict.TryGetValue(s, out replace))
      yield return replace;
    else
      yield return s;
  }
}
IEnumerable替换(IEnumerable源、IEnumerable from seq、IEnumerable to seq)
{
var dict=fromSeq.Zip(toSeq,(fr,to)=>new{fr=fr,to=to})
.ToDictionary(a=>a.Fr,a=>a.To);
foreach(源中的var s)
{
不可替代;
if(dict.TryGetValue(s,out替换))
退换货;
其他的
收益率;
}
}

好的,下面是基于您编辑的问题的答案。当然完全没有经过测试

static IEnumerable<T> Replace<T>(IEnumerable<T> source, IDictionary<IEnumerable<T>, IEnumerable<T>> values)
{
  foreach (var kvp in values)
    source = ReplaceOne(source, kvp.Key, kvp.Value);
  return source;
}

static IEnumerable<T> ReplaceOne<T>(IEnumerable<T> source, IEnumerable<T> fromSeq, IEnumerable<T> toSeq)
{
  var sArr = source.ToArray();

  int replLength = fromSeq.Count();
  if (replLength != toSeq.Count())
    throw new NotSupportedException();

  for (int idx = 0; idx <= sArr.Length - replLength; idx++)
  {
    var testSeq = Enumerable.Range(idx, replLength).Select(i => sArr[i]);
    if (testSeq.SequenceEqual(fromSeq))
    {
      Array.Copy(toSeq.ToArray(), 0, sArr, idx, replLength);
      idx += replLength - 1;
    }
  }

  return sArr;
}
静态IEnumerable替换(IEnumerable源代码,IDictionary值)
{
foreach(值中的var kvp)
source=ReplaceOne(source,kvp.Key,kvp.Value);
返回源;
}
静态IEnumerable ReplaceOne(IEnumerable源、IEnumerable from seq、IEnumerable to seq)
{
var sArr=source.ToArray();
int replength=fromSeq.Count();
if(replLength!=toSeq.Count())
抛出新的NotSupportedException();
对于(int-idx=0;idx-sArr[i]);
if(testSeq.SequenceEqual(fromSeq))
{
Copy(toSeq.ToArray(),0,sArr,idx,replLength);
idx+=replLength-1;
}
}
返回sArr;
}

这很好。如果
source
有重复,此解决方案仅为每个
i
替换
source
中的一个元素。PS,您的签名不太正确,请更改值以具有IEnumerable@MAfifi-我不明白,为什么?您将尝试对类型为T的数组进行索引。这不起作用,因为索引器总是希望它是一个int。请参见下面的示例。这是一种非常低效且难看的方法,但效果=>将列表转换为字符串并使用string.Replace<代码>var dest=String.Join(“,source.Select(x=>”[“+x+”])。替换(String.Join(“,fromArray.Select(x=>”[“+x+”])),String.Join(“,toArray.Select(x=>”[“+x+”))。拆分(新字符[]{'[',']},StringSplitOptions.RemoveEmptyEntries)。选择(x=>Int32.Parse(x)).ToArray()
从数组到数组的
到数组的
长度是否总是两个?在编辑之后,所有替换的顺序似乎变得很重要。但是,
字典
的顺序没有很好的定义。嗯,在
源代码
中没有看到您对连续元素的编辑。看起来不错,将源代码转换为数组并每次计算值可能会影响性能,但正如我所说,如果需要计数和索引器,我可以使用IList而不是IEnumerable。我会尽快尝试一下。如果
replLength
可能为零,您应该将
for
循环放入
If(replLength!=0)
块。另外请注意,您可能无法知道
foreach
IDictionary
中的运行顺序。如果源为
a、b、c
且一个替换为
a→m
和另一个替代品是
c→a
(或
a→k
),则替换顺序很重要。你不能用标准的
字典
很好地控制顺序。我想字典会像列表一样迭代,谢谢你提供的信息。我可以使用IEnumerable作为参数类型。该方法的用户可能希望根据其需要使用列表e.t.c。
var replaced = source.Zip(fromArray.Zip(toArray, (x, y) => new {From = x, To = y}),
                                      (x, y) => new {Src = x, Dest = y}).
                Select(x => x.Src == x.Dest.From ? x.Dest.To : x.Src);
IEnumerable<T> Replace(IEnumerable<T> source,
    IDictionary<IEnumerable<int>, IEnumerable<T>> values) 
{ 
    // "values" parameter holds the pairs that I want to replace. 
    // "source" can be `IList<T>` instead of `IEnumerable<T> if an indexer 
    // is needed but I prefer `IEnumerable<T>`.

    IList<T> sourceAsList = source as IList<T>;
    if (sourceAsList == null)
    {
        sourceAsList = source.ToList();
    }

    foreach (var kvp in values)
    {
        // repeat same thing as above.
    }
} 
IEnumerable<T> Replace<T>(IEnumerable<T> source, IEnumerable<T> fromSeq, IEnumerable<T> toSeq)
{
  var dict = fromSeq.Zip(toSeq, (fr, to) => new { Fr = fr, To = to })
    .ToDictionary(a => a.Fr, a => a.To);

  foreach (var s in source)
  {
    T replace;
    if (dict.TryGetValue(s, out replace))
      yield return replace;
    else
      yield return s;
  }
}
static IEnumerable<T> Replace<T>(IEnumerable<T> source, IDictionary<IEnumerable<T>, IEnumerable<T>> values)
{
  foreach (var kvp in values)
    source = ReplaceOne(source, kvp.Key, kvp.Value);
  return source;
}

static IEnumerable<T> ReplaceOne<T>(IEnumerable<T> source, IEnumerable<T> fromSeq, IEnumerable<T> toSeq)
{
  var sArr = source.ToArray();

  int replLength = fromSeq.Count();
  if (replLength != toSeq.Count())
    throw new NotSupportedException();

  for (int idx = 0; idx <= sArr.Length - replLength; idx++)
  {
    var testSeq = Enumerable.Range(idx, replLength).Select(i => sArr[i]);
    if (testSeq.SequenceEqual(fromSeq))
    {
      Array.Copy(toSeq.ToArray(), 0, sArr, idx, replLength);
      idx += replLength - 1;
    }
  }

  return sArr;
}