从锯齿状阵列中选择单个元素

时间:2012-07-11 21:23:54

标签: c# .net linq

我正在研究一个让我的大脑融化的问题,尽管我不认为这应该是这么难。我的例子很长,所以我会尽量避免我的问题!

我有一个Array对象,其中包含一些也是Arrays的元素。例如:

customerAddresses = new customer_address[]
{
  new    // address #1
  {
    customer_id = 6676979,
    customer_address_seq = 1,
    customer_address_match_codes = new []
    {
      new
      {
        customer_address_seq = 1,
        customer_id = 6676979,
        customer_match_code_id = 5
      }
    }
  },
  new    // address #2
  {
    customer_id = 6677070,
    customer_address_seq = 1,
    customer_address_match_codes = new []
    {
      new
      {
        customer_address_seq = 1,
        customer_id = 6677070,
        customer_match_code_id = 4
      },
      new
      {
        customer_address_seq = 1,
        customer_id = 6677070,
        customer_match_code_id = 5
      },
      new
      {
        customer_address_seq = 1,
        customer_id = 6677070,
        customer_match_code_id = 3
      }
    }
  },
  new    // address #3
  {
    customer_id = 6677070,
    customer_address_seq = 2,
    customer_address_match_code = new []
    {
      new
      {
        customer_address_seq = 2,
        customer_id = 6677070,
        customer_match_code_id = 4
      },
      new
      {
        customer_address_seq = 2,
        customer_id = 6677070,
        customer_match_code_id = 5
      }
    }
  }
};

如您所见,数组包含许多地址记录,每个customer_idcustomer_address_seq组合有一条记录。我要做的是根据以下规则找到最匹配的customer_address

  • 必须customer_match_code_id等于4,且必须有一个等于5
  • 如果customer_match_code_id等于3,则认为customer_address更强烈匹配。

根据上述规则,第二个customer_address元素是“最佳匹配”。但是,这个问题的最后一点复杂性是可能存在多个“最佳匹配”。我需要处理这种情况的方法是将customer_address记录设为最小customer_id和最小customer_address_seq

我当时认为使用LINQ是我最好的选择,但我没有足够的经验,所以我只是继续旋转我的车轮。

4 个答案:

答案 0 :(得分:0)

未经测试且名称不同,但这应该让你去

            customer cb = null;
            customer[] cs = new customer[] {new customer()};

            foreach (customer c in cs.OrderBy(x => x.id).ThenBy(y => y.seq))
            {
                if(c.addrs.Any(x => x.num == "5"))
                {
                    if(c.addrs.Any(x => x.num == "3"))
                    {
                        if (cb == null) cb = c;
                        if (c.addrs.Any(x => x.num == "2"))
                        {
                            cb = c;
                            break;
                        }
                    }
                }
            }

答案 1 :(得分:0)

这听起来像是LINQ的工作

var bestMatch = (from address in DATA
where address.customer_address_match_code.Any(
  x => x.customer_match_code_id == 4)
where address.customer_address_match_code.Any(
  x => x.customer_match_code_id == 5)
select address).OrderBy(
  x => x.customer_address_match_code.Where(
    y => y.customer_match_code_id >= 3)
  .OrderBy(y => y.customer_match_code_id)
  .First()
  .customer_match_code_id).FirstOrDefault();

我的理论是:选择同时包含customer_match_code_id == 4和customer_match_code_id == 5的地址。然后按照他们拥有的至少为3的最低customer_match_code_id对它们进行排序,然后选择第一个。如果customer_match_code_id等于3,那么选择那个,如果没有,则选择其他一些。如果4和5都不匹配,则返回null。

未测试。

答案 2 :(得分:0)

在LINQ中似乎很直接:

var query =
    from ca in customerAddresses
    where ca.customer_address_match_codes.Any(
        mc => mc.customer_match_code_id == 4)
    where ca.customer_address_match_codes.Any(
        mc => mc.customer_match_code_id == 5)
    orderby ca.customer_id
    orderby ca.customer_address_seq
    orderby ca.customer_address_match_codes.Any(
        mc => mc.customer_match_code_id == 3) descending
    select ca;

var result = query.Take(1);

看起来如何?

答案 3 :(得分:0)

必须对您的班级进行更改,以便您实际将某个收藏集分配给某个收藏集:

customer_address_match_codes = new customer_address_match_code[]
{
  new
  {
    customer_address_seq = 1,
    customer_id = 6676979,
    customer_match_code_id = 5
  }
}

然后这是我测试过的LINQ并执行您指定的内容:

var result = (from c in customerAddresses
    let isMatch = c.customer_address_match_codes
                     .Where (cu => cu.customer_match_code_id == 4).Any () &&
                  c.customer_address_match_codes
                     .Where (cu => cu.customer_match_code_id == 5).Any ()
    let betterMatch = isMatch && c.customer_address_match_codes
                  .Where (cu => cu.customer_match_code_id == 3).Any () ? 1 : 0
    where isMatch == true
    orderby betterMatch descending, c.customer_id, c.customer_address_seq
    select c)
    .FirstOrDefault ();

我在这里使用匿名类型的数据编写了一个示例:http://ideone.com/wyteM