Calculate difference in property - arrays

I have converted a list of JSON objects to a generic list.
The Data structure on the items is as following
public class Person
{
private string Name;
private int Age;
private string Weightloss;
}
The Weightloss string is of type "109-102" and I need to calculate how much each person has lost in weight since they signed up. I my examlpe it'd be 7. How to I, using LINQ Method syntax, calculate each weight loss (or gain). I assume I'll need to split up the string but I'm not really sure how

Rather odd question, but if Linq is what you want, here is how one can go about it:
Create a function inside your class to calculate the weight difference:
public class Person
{
//Constructor
public Person(string name, int age, string weightLoss)
{
Name = name;
Age = age;
Weightloss = weightLoss;
}
public string Name;
private int Age;
private string Weightloss;
/// <summary>
/// Calculates the weight difference from the WeightLoss property.
/// </summary>
/// <returns></returns>
public int GetWeightLoss()
{
//Get the values
var parts = Weightloss.Split('-')
.Select(value => Convert.ToInt32(value))
.ToArray();
//Calculate the difference
var difference = parts[0] - parts[1];
return difference;
}
}
Not clean and I personally dislike it but it's homework so...
I added a constructor for initialization and changed the Name field to public so you can output it:
var list = new List<Person>()
{
new Person("Juan", 30, "109-102"),
new Person("Max", 35, "119-103"),
new Person("John", 40, "109-105"),
};
//Figure out the largest loss
var maxLossPerson = list.OrderByDescending(p => p.GetWeightLoss()).First();
Console.WriteLine($"{maxLossPerson.Name} lost the most with {maxLossPerson.GetWeightLoss()} pound(s)");
Output:
Max lost the most with 16 pound(s)

You're either going to use a string split or a regular expression.
Assuming your string is always formatted "Weight1-Weight2", a string split would be fairly simple:
public int[] ParseWeights(string weightString) {
var weights = weightString.Split('-');
var beginningWeight = Convert.ToInt32(weights[0]);
var endingWeight = Convert.ToInt32(weights[1]);
return new int[] {beginningWeight, endingWeight};
}

Add another property to Person:
public class Person
{
private string Name;
private int Age;
private string Weightloss;
public int WeightLost
{
get
{
int[] values = Weightloss.Split('-').Select(i => int.Parse(i)).ToArray();
return values[0] - values[1];
}
}
}

If you look for a even more Linq way, you can use the follow way:
private string Weightloss;
public int WeightLossInt => Weightloss
.Split('-')
.Select((value, index) => index == 0 ? int.Parse(value) : -int.Parse(value))
.Sum();
}

Related

How do I call this list from another class in C#?

I am still new to the whole C# thing but I found this code posted from grovesNL about 5 years ago which I believe will work.
namespace DataAccessClass
{
public class FileReader
{
static void Main(string[] args)
{
List<DailyValues> values = File.ReadAllLines("C:\\Users\\Josh\\Sample.csv")
.Skip(1)
.Select(v => DailyValues.FromCsv(v))
.ToList();
}
}
public class DailyValues
{
DateTime Date;
decimal Open;
decimal High;
decimal Low;
decimal Close;
decimal Volume;
decimal AdjClose;
public static DailyValues FromCsv(string csvLine)
{
string[] values = csvLine.Split(',');
DailyValues dailyValues = new DailyValues();
dailyValues.Date = Convert.ToDateTime(values[0]);
dailyValues.Open = Convert.ToDecimal(values[1]);
dailyValues.High = Convert.ToDecimal(values[2]);
dailyValues.Low = Convert.ToDecimal(values[3]);
dailyValues.Close = Convert.ToDecimal(values[4]);
dailyValues.Volume = Convert.ToDecimal(values[5]);
dailyValues.AdjClose = Convert.ToDecimal(values[6]);
return dailyValues;
}
}
}
I am trying to read a csv file skipping the header and get it into a list that is accessible from another class. So my Architecture is DataAccessClass that has a class called FileReader and a class called Values. My task is to read this csv file into class FileReader and then to create an object list to hold it in the class Values. When I go to the Values class to call it I can't figure it out. This is how I am trying to call it. It is saying DailyValues.FromCsv(string) is a method that is not valid.
public List<string> GetList()
{
return DataAccessClass.DailyValues.FromCsv.dailyValues;
}
I want to be able to access this list further up the stack.
Your expression DataAccessClass.DailyValues.FromCsv.dailyValues is the culprit.
DataAccessClass.DailyValues.FromCsv is valid, and references the static method named FromCsv in the class DataAccessClass.DailyValues. But then going on by adding .dailyValues is incorrect. It is a method, nothing to peek into and extract stuff using ..
You could (if that was the intention) call the function, and directly work with the result:
DataAccessClass.DailyValues.FromCsv(some_csv_string) is an expression of type DailyValues. There you could then access - as an example - 'High' with:
DailyValues dv;
dv = DataAccessClass.DailyValues.FromCsv(some_csv_string);
dosomething(dv.High);
But for that to work, High would have to have the visibility of public.

Storing variables of GameObjects into Array [Unity]

I have 3 kinds of GameObject, namely blueBook, redBook and greenBook. There are 2 blueBook, 7 redBook and 4 greenBook in the scene.
They are each assigned with the following example script that have 3 properties.
public class blueBook : MonoBehaviour {
public string type = "BlueBook";
public string colour = "Blue";
public float weight;
float s;
void Start () {
float weightValue;
weightValue = Random.value;
weight = Mathf.RoundToInt (700*weightValue+300);
s=weight/1000; //s is scale ratio
transform.localScale += new Vector3(s,s,s);
}
// Update is called once per frame
void Update () {
}
}
In the new class, I want to take all the variables of the GameObject (type, colour, weight) and store them inside an array. How to do this?
After they are all stored inside the array, user will input an weight. Then another class will search through all the info to delete both the array and GameObject(in the scene) with the same amount of weight.
Thank you.
UPDATE
blueBook.cs
public class blueBook: MonoBehaviour {
public string type = "blueBook";
public string colour = "Red";
public float weight;
float s;
void Start () {
float weightValue;
weightValue = Random.value;
weight = Mathf.RoundToInt (500*weightValue+100);
s=weight/1000; //s is scale ratio
transform.localScale += new Vector3(s,s,s);
Debug.Log(weight);
}
// Update is called once per frame
void Update () {
}
}
block.cs
public class block: MonoBehaviour{
public List<GameObject> players;
void Start()
{ Debug.Log(players[1].GetComponent<blueBoook>().weight);
}
// Update is called once per frame
void Update () {
}
The debug.log for block.cs displayed 0 everytime eventho it display otherwise in debug.log of bluebook.cs. It is because it displayed the initial number? I don know wat is wrong
For all blocks in one list you can create a script that has a public list and you drag all your gameobjects into the list in the inspector.
using System.Collections.Generic;
public class ObjectHolder : MonoBehaviour
{
public List<GameObject> theBooks;
// You can remove by weight e.g. like this
public void DeleteByWeight(float inputWeight)
{
for(int i = theBooks.Count - 1; i >= 0; i--)
{
if(theBooks[i].GetComponent<Book>().weight == inputWeight)
Destroy(theBooks[i]);
theBooks.RemoveAt(i);
}
}
}
}
The script on the blocks needs to be renamed to the same name for all (Book in my example). From your code that is no problem since they only differ in the value of the members.

C# ComboBox string array with int

Well, the title is a bit confusing but I want to ask if it possible to have a array with string and int inside ?
For example:
string[] versions = new string[] { "Normal",1, "Expert",2, "Pro",3 };
comboBox.Items.AddRange(versions);
So if I would select Normal, the version integer would be set to 1. In my programm I got alot if items in my comboBox, and I don't want to have 50+ if functions to set the integer.
Sorry for my bad english.
What you are looking for is an Object containing the string and int properties/fields. Try the following:
public class Version // You can replace "Version" with any name you'd like
{
public string Name { get; set; }
public int Value { get; set; }
}
Then you have an array of your Version-objects you can use:
Version[] versions = new Version[] {
new Version { Name = "Normal", Value = 1 },
new Version { Name = "Expert", Value = 2 },
new Version { Name = "Pro", Value = 3 }
};
I couldn't tell which programming language you are using (although I assumed .NET C# based on the code given).

Object array assignment changing parameters

I'm creating an array of different animal objects from the same super class and then using a for loop I'm retrieving a description of each animal using a method from another class but when I assign each new animal to the array it changes the name and type of each to that of the last animal. How do I get it to stop changing the parameters for each animal?
Here's my code now:
I have constructors for each type of animal listed with different descriptions for each type.
Animal[] family = new Animal[5];
family[0] = new Dog("Wrex", "dog");
family[1] = new Wolf("Fenrir", "wolf");
family[2] = new Snake("Kaa","snake");
family[3] = new Snake("Nagini", "snake");
family[4] = new Chameleon("David", "chameleon");
for(int i = 0; i < 5; i++)
{
family[i].describe();
}
This is what it prints out:
David is a chameleon.
David barks.
David moves on four legs.
David gets food from its owner.
David eats by chewing.
David is a chameleon.
David howls.
David moves on four legs.
David gets food by hunting in packs.
David eats by chewing.
Edit
My describe method is different for each animal class but they all follow this format:
public void describe()
{
System.out.println(Chameleon.getName()+ " is a " +Chameleon.getType()+ ".");
makeSound();
move();
getFood();
eatFood();
}
Edit 2
Here is a rough outline of each class and subclass
public class Animal {
private static String name;
private static String type;
public Animal(String name, String type)
{
Animal.name = name;
Animal.type = type;
}
public static String getName() {
return name;
}
public void setName(String name) {
Animal.name = name;
}
public static String getType() {
return type;
}
public void setType(String type) {
Animal.type = type;
}
public class Mammal extends Animal {
public Mammal(String name, String type)
{
super(name, type);
}
}
reptile is the same as mammal
each of the last subclass looks like this with the describe method posted above
public class Chameleon extends Reptile{
public Chameleon(String name, String type)
{
super(name, type);
}
static !!!
remove the static keyword. That's the only problem. Read more about it here
use this and change things accordingly
private String name;
private String type;
Variables name and type are declared as static in class "Animal". Therefore they are shared by all instances of the "Animal" class.

Changing the number of a var inside an array, does not change the var result itself?

Not quite sure if I asked correctly, but basically I have an array that stores some var(int/numbers). And when I loop through the array changing the numbers of the var, at the end the number seems still unchanged. You would have a better idea of what I'm talking about base on the below code.
private var _numArray:Array = new Array()
private var _no1:int
private var _no2:int
public function Main():void
{
_no1 = 10
_no2 = 20
_numArray.push(_no1)
_numArray.push(_no2)
while (_numArray.length)
{
_numArray[0] = 0
_numArray.splice(0, 1)
}
trace(_no1, _no2) // still returning 10 , 20
}
This is how primitives work. When you push a primitive like int, Number etc. to an array or pass to a function they are passed by value. So _numArray[0] and _no1 are different things. Change is one does not affect another.
If you want the array to store references instead of values, you'll need to use a non-primitive datatype. Among the primitive datatypes are int, uint, Number, Boolean and String. A non-primitive (complex) datatype is anything else.
// SpecialNumber.as
public class SpecialNumber
{
public var value:Number;
public function SpecialNumber(value:Number)
{
this.value = value;
}
}
// Main.as
public class Main
{
public function Main()
{
var no1:SpecialNumber = new SpecialNumber(5);
var no2:SpecialNumber = new SpecialNumber(10);
var array:Array = [no1, no2];
array[0].value += 10;
array[1].value += 60;
trace(no1.value, no2.value) // Output is "15 70"
}
}

Resources