按价格排序列表,由列表内项目的子字符串计算#

Posted

技术标签:

【中文标题】按价格排序列表,由列表内项目的子字符串计算#【英文标题】:Sort list by a price, calculated by substrings from item inside list c# 【发布时间】:2021-09-30 16:51:57 【问题描述】:

我有一个如下所示的列表:

      Apple - 67 $ - 345 PIECES - 19:03
      Banana - 45 $ - 341 PIECES - 12:02
      Monkey - 34 $ - 634 PIECES - 16:01

我想按(金额*金额)的排序结果排序该列表,类似于“最高订单排名”

 finalResultOfTradeFiltering = finalResultOfTradeFiltering.OrderBy(x => Convert.ToDecimal(FindTextBetween(x,"-","$").Replace(" ", String.Empty)) * Convert.ToInt32(FindTextBetween(x, "-", "PIECES").Replace(" ", String.Empty))).ToList();

public string FindTextBetween(string text, string left, string right)
        
            // TODO: Validate input arguments

            int beginIndex = text.IndexOf(left); // find occurence of left delimiter
            if (beginIndex == -1)
                return string.Empty; // or throw exception?

            beginIndex += left.Length;

            int endIndex = text.IndexOf(right, beginIndex); // find occurence of right delimiter
            if (endIndex == -1)
                return string.Empty; // or throw exception?

            return text.Substring(beginIndex, endIndex - beginIndex).Trim();
        

但是我的代码不断崩溃,说明格式不正确

有什么线索吗?

【问题讨论】:

它将基于FindTextBetween 代码,但我的猜测是FindTextBetween(x, "-", "PIECES") 从第一个- 中找到文本,因此您尝试格式化67$-345 而不是@ 987654328@。请附上FindTextBetween 代码,以便我们确认是否是问题所在。 你应该写一个类,可以使用类类型将字符串列表转换为列表。 我很确定我已经在 foreach 循环中测试了 FindTextBetween,它正确地输出了金额和件数,所以没有错 如果可能尝试使用Regex,而不是查找索引并提取子字符串 是的,问题正如我所怀疑的那样。 FindTextBetween- 的第一次出现开始。因此,您要么需要更新它以传入它应该开始的索引,要么告诉它跳过第一次出现。或者更好的是编写一个方法来将整个字符串解析为一个带有值的类,然后在你的代码中使用它。 【参考方案1】:

首先这样做:

public class Trade

    public string Product get;set;
    public decimal Price get;set;
    public int Quantity get;set;
    public string Time get;set; //Make this a DateTime or new TimeOnly later
    public string OriginalLine get;set;

    public static Trade Parse(string input)
    
        var result = new Trade();
        result.OriginalLine = input;

        //example line
        //Apple - 67 $ - 345 PIECES - 19:03
        var exp = new RegEx(@" - (\d+) [$] - (\d+) PIECES - (\d1,2:\d2)");
        var groups = exp.Match(input).Groups;

        result.Price = Convert.ToDecimal(groups[1].Value);
        result.Quantity = Convert.ToInt32(groups[2].Value);
        result.Time = groups[3].Value;

        int EndMarker = input.IndexOf(" - ");
        result.Product = input.SubString(0, EndMarker).Trim();
        return result;
    

然后像这样使用类型:

var result = finalResultOfTradeFiltering.
    Select(t => Trade.Parse(t)).
    OrderByDescending(t => t.Price * t.Quantity).
    Select(t => t.OriginalLine);

请注意缺少ToList() 呼叫。尽可能坚持使用 IEnumerable,而不是在每一步之后再次转换为 List,这将节省 RAM,有时还会节省 CPU,从而使代码更快、更高效。在您真正需要之前不要转换为列表,这可能比您想象的要晚得多。

如果您能够在处理过程中更早地将字符串转换为对象,并且在所有其他处理完成之前不将它们返回为字符串,那就更好了。

【讨论】:

感谢 Joel 也是一个很好的答案,还可以获得计算值(例如,Apple - 67 $ - 345 PIECES - 19:03 - 23.115 $)我可以做这样的事情吗... = > t.originalline + (t.Price * t.Quantity) ? 不,原行是一个字符串。 始终注意值的数据类型。您只需要 t.Price * t.Quanity 部分。【参考方案2】:

您可以使用模式来获取数字,然后使用排序进行计算。

(\d+) \$ - (\d+) PIECES
(\d+) \$ 为钱捕获组 1,匹配 1+ 位数字、空格和 $ - 字面匹配 (\d+) PIECES捕获组2的金额,匹配1+数字和 PIECES

假设模式匹配所有给定的字符串:

List<string> finalResultOfTradeFiltering = new List<string>() 
     "Apple - 67 $ - 345 PIECES - 19:03",
     "Banana - 45 $ - 341 PIECES - 12:02",
     "Monkey - 34 $ - 634 PIECES - 16:01"
;
var regex = @"(\d+) \$ - (\d+) PIECES";
finalResultOfTradeFiltering.Sort((a, b) => 
    var matchA = Regex.Match(a, regex);
    var matchB = Regex.Match(b, regex);
    var valueA = int.Parse(matchA.Groups[1].Value) * int.Parse(matchA.Groups[2].Value);
    var valueB = int.Parse(matchB.Groups[1].Value) * int.Parse(matchB.Groups[2].Value);
    return valueB.CompareTo(valueA);
);

finalResultOfTradeFiltering.ForEach(s => Console.WriteLine(s));

输出

Apple - 67 $ - 345 PIECES - 19:03
Monkey - 34 $ - 634 PIECES - 16:01
Banana - 45 $ - 341 PIECES - 12:02

【讨论】:

非常感谢,我该如何实际使用它来进一步输出 price * pieces 的值?像这样的东西:Apple - 67 $ - 345 PIECES - 19:03 - 23.115 $ ? @HassanBrate 您可以再次格式化列表中的项目,然后根据需要格式化数字。见ideone.com/FPd8j5

以上是关于按价格排序列表,由列表内项目的子字符串计算#的主要内容,如果未能解决你的问题,请参考以下文章

根据子列表中的第二个元素按字母顺序对列表进行排序,但不区分大小写[重复]

搜索元组列表以查找匹配子字符串的算法方法?

LeetCode 884. 两句话中的不常见单词 / 1342. 将数字变成 0 的操作次数(计算二进制长度统计1的个数) / 1763. 最长的美好子字符串(分治)

从列表创建组合,如果子字符串到分隔符字符位于列表项的 1 个以上的子元素中,则从列表中删除

python:按子列表中的项目对列表列表进行排序[重复]

按子文件夹编号对目录列表进行排序