I have a space separated list of int like below:
1 -2 3 1 -8 3 -2 5
I need an absolute sum of a specific range of that list i.e. from 4th index to 6th index. The result will be 10(from abs(-8-2)).
I can get the perfect result by using below code:
List<int> _subList = new List<int>();
string _input = Console.ReadLine();
List<int> _list = _input.Split(' ').Select(n => Convert.ToInt32(n)).ToList<int>();
var k =Math.Abs(_list.GetRange(3, 3).Where(x=>x<0).Sum());
Console.WriteLine(k);
But is there any way to do it without using Linq?
CodePudding user response:
But is there any way to do it without using Linq?
List<int> data = new List<int>() { 1, -2, 3, 1, -8, 3, -2, 5 };
long sum = 0;
var minIndex = 4;
var maxIndex = 6;
for (int i = minIndex; i <= maxIndex && i < data.Count; i )
{
if (data[i] < 0)
{
sum -= data[i];
}
}
Above is using a for loop with the appropriate indices to get the values out, and using -
rather than
and Abs
to get the output you expect.
If you explicitly need the string parsing:
string input = Console.ReadLine();
var data = input?.Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) ?? Array.Empty<string>();
long sum = 0;
var minIndex = 4;
var maxIndex = 6;
for (int i = minIndex; i <= maxIndex && i < data.Length; i )
{
if (int.TryParse(data[i], out var val) && val < 0)
{
sum -= val;
}
}
Note you need to use ?.
with the Split
to handle Console.ReadLine
returning null
. And StringSplitOptions
simplifies the trimming of whitespace.
CodePudding user response:
This is a great use case for LINQ extension methods.
- split the string to get the constituent integer strings
- skip to start offset
- take desired element count (endOffset - startOffset 1)
- convert string values to integers via projection
- filter for negative values
- project negation
- aggregate the sum
.
string input = "...";
var startOffset = 4;
var endOffset = 6;
var absSum = input.Split(' ')
.Skip(startOffset)
.Take(endOffset - startOffset 1)
.Select(s => Convert.ToInt32(s))
.Where(i => 0 > i)
.Select(i => -i)
.Sum();
Without LINQ extension methods:
var targetElements = input.Split(' ')
//.Skip(startOffset).Task(endOffset - startOffset 1)
.AsSpan(startOffset, endOffset - startOffset 1);
var absSum = 0;
foreach(var element in targetElements)
{
//.Select(s => Convert.ToInt32(s))
var i = Convert.ToInt32(element);
//.Where(i => 0 > i)
if( 0 > i )
{
//.Sum()
absSum = i;
}
}
// we know sum is negative so negate for absolute value
absSum = -absSum;
CodePudding user response:
List<int> _subList = new List<int>();//1
string _input = Console.ReadLine();//2
List<int> _list = _input.Split(' ')//3
.Select(n => Convert.ToInt32(n))//4
.ToList<int>();//5
var k =Math.Abs(_list.GetRange(3, 3)//6
.Where(x=>x<0).Sum());//7
Console.WriteLine(k);
I think code below is right
- In //1 creates empty List
- In //2 read space as string
- In //3 getting numbers to int List
- In //4 Iterating and converting to numbers from string to int
- In //5 get All as List in type int
- In //6 I think Math.abs clear,GetRange(3,3) is same begin from range in math (3,3 3] thats 4,5,6
- In //7 Sum() for getting sum
CodePudding user response:
List<int> _subList = new List<int>();
string _input = Console.ReadLine();
List<int> _list = _input.Split(' ').Select(n => Convert.ToInt32(n)).ToList<int>();
var k =Math.Abs(_list.GetRange(3, 3).Where(x=>x<0).Sum());
Console.WriteLine(k);
Here _list.GetRange(3, 3)
will create the sublist
and then Where(x=>x<0).Sum()
pick the negative values and sum it up
and ulimately Math.Abs()
will give the absolute value
But here i have used System.Linq; If anyone can provide with better solution other than manual looping would be appriciated