Remove items earlier than a fix date and replace the first occurrence
Based on a list of a typed class like
class CostCenter
{
string center;
string percentage;
DateTime start;
}
I have a list of these elements like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/01/01"}
- {"yy", 90, "2010/01/01"}
- {"100", 50, "2009/07/03"}
- {"101", 50, "2009/07/03"}
taking into account that I want to get rid of all of the elements (list) that have a start date earlier or equal than a fixed(_earliestDate), also this fixed data will replace the earliest match. In this example the earliest date is "2010/11/01", therefore "xx" and "yy" start date is replaced to "2010/11/01".
The output should be like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/11/01"}
- {"yy", 90, "2010/11/01"}
I have created the following code:
string dateToReplace = null;
bool earliestFound = false;
foreach (var item in list.OrderByDescending(x => DateTime.Parse(x.start)).ToList())
{
if (earliestFound) //already marked, safe to remove others
{
list.Remove(item);
continue;
}
if (!string.IsNullOrEmpty(dateToReplace)) //remaining matches
{
if (string.Equals(item.start, dateToReplace))
{
item.start = _earliestDate;
continue;
}
else
{
earliestFound = true;
list.Remove(item);
continue;
}
}
if (item.start <= _earliestDate) //first earliest or same, more required
{
dateToReplace = item.start;
item.start = _earliestDate;
}
}
dateToReplace and earliestFound will be used as flags in the code to determine when to loop.
Somehow I think it is not the best option, do you have any suggestion on how to make it easier to understand or efficient?
c#
|
show 12 more comments
Based on a list of a typed class like
class CostCenter
{
string center;
string percentage;
DateTime start;
}
I have a list of these elements like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/01/01"}
- {"yy", 90, "2010/01/01"}
- {"100", 50, "2009/07/03"}
- {"101", 50, "2009/07/03"}
taking into account that I want to get rid of all of the elements (list) that have a start date earlier or equal than a fixed(_earliestDate), also this fixed data will replace the earliest match. In this example the earliest date is "2010/11/01", therefore "xx" and "yy" start date is replaced to "2010/11/01".
The output should be like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/11/01"}
- {"yy", 90, "2010/11/01"}
I have created the following code:
string dateToReplace = null;
bool earliestFound = false;
foreach (var item in list.OrderByDescending(x => DateTime.Parse(x.start)).ToList())
{
if (earliestFound) //already marked, safe to remove others
{
list.Remove(item);
continue;
}
if (!string.IsNullOrEmpty(dateToReplace)) //remaining matches
{
if (string.Equals(item.start, dateToReplace))
{
item.start = _earliestDate;
continue;
}
else
{
earliestFound = true;
list.Remove(item);
continue;
}
}
if (item.start <= _earliestDate) //first earliest or same, more required
{
dateToReplace = item.start;
item.start = _earliestDate;
}
}
dateToReplace and earliestFound will be used as flags in the code to determine when to loop.
Somehow I think it is not the best option, do you have any suggestion on how to make it easier to understand or efficient?
c#
Does your code works without exception? Usually, it is not allowed to alter a list, while iterating over it at the same time... Regarding your question: a different approach may be the linq Where() method to only fetch the items from the list that should be removed or updated.
– Nicolas
Nov 26 '18 at 13:45
Wow, it looks like a very complicated way to do something very simple. At the same time, I didn't understand what you are trying to achieve.
– Yeldar Kurmangaliyev
Nov 26 '18 at 13:45
1
@YeldarKurmangaliyev this seem to be a cleanup of a history alike list
– Nicolas
Nov 26 '18 at 13:46
@DanielV, Instead of removing items from list, can we create new list with filtered results? If Yes then we can do it in one line
– Prasad Telkikar
Nov 26 '18 at 13:52
1
@PrasadTelkikar yes, there is no restriction to remove items from the list
– DanielV
Nov 26 '18 at 13:55
|
show 12 more comments
Based on a list of a typed class like
class CostCenter
{
string center;
string percentage;
DateTime start;
}
I have a list of these elements like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/01/01"}
- {"yy", 90, "2010/01/01"}
- {"100", 50, "2009/07/03"}
- {"101", 50, "2009/07/03"}
taking into account that I want to get rid of all of the elements (list) that have a start date earlier or equal than a fixed(_earliestDate), also this fixed data will replace the earliest match. In this example the earliest date is "2010/11/01", therefore "xx" and "yy" start date is replaced to "2010/11/01".
The output should be like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/11/01"}
- {"yy", 90, "2010/11/01"}
I have created the following code:
string dateToReplace = null;
bool earliestFound = false;
foreach (var item in list.OrderByDescending(x => DateTime.Parse(x.start)).ToList())
{
if (earliestFound) //already marked, safe to remove others
{
list.Remove(item);
continue;
}
if (!string.IsNullOrEmpty(dateToReplace)) //remaining matches
{
if (string.Equals(item.start, dateToReplace))
{
item.start = _earliestDate;
continue;
}
else
{
earliestFound = true;
list.Remove(item);
continue;
}
}
if (item.start <= _earliestDate) //first earliest or same, more required
{
dateToReplace = item.start;
item.start = _earliestDate;
}
}
dateToReplace and earliestFound will be used as flags in the code to determine when to loop.
Somehow I think it is not the best option, do you have any suggestion on how to make it easier to understand or efficient?
c#
Based on a list of a typed class like
class CostCenter
{
string center;
string percentage;
DateTime start;
}
I have a list of these elements like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/01/01"}
- {"yy", 90, "2010/01/01"}
- {"100", 50, "2009/07/03"}
- {"101", 50, "2009/07/03"}
taking into account that I want to get rid of all of the elements (list) that have a start date earlier or equal than a fixed(_earliestDate), also this fixed data will replace the earliest match. In this example the earliest date is "2010/11/01", therefore "xx" and "yy" start date is replaced to "2010/11/01".
The output should be like this:
- {"a", 70, "2019/11/10"}
- {"b", 30, "2019/11/10"}
- {"A", 40, "2018/10/05"}
- {"B", 60, "2018/10/05"}
- {"xx", 10, "2010/11/01"}
- {"yy", 90, "2010/11/01"}
I have created the following code:
string dateToReplace = null;
bool earliestFound = false;
foreach (var item in list.OrderByDescending(x => DateTime.Parse(x.start)).ToList())
{
if (earliestFound) //already marked, safe to remove others
{
list.Remove(item);
continue;
}
if (!string.IsNullOrEmpty(dateToReplace)) //remaining matches
{
if (string.Equals(item.start, dateToReplace))
{
item.start = _earliestDate;
continue;
}
else
{
earliestFound = true;
list.Remove(item);
continue;
}
}
if (item.start <= _earliestDate) //first earliest or same, more required
{
dateToReplace = item.start;
item.start = _earliestDate;
}
}
dateToReplace and earliestFound will be used as flags in the code to determine when to loop.
Somehow I think it is not the best option, do you have any suggestion on how to make it easier to understand or efficient?
c#
c#
edited Nov 26 '18 at 14:59
DanielV
asked Nov 26 '18 at 13:37
DanielVDanielV
78211741
78211741
Does your code works without exception? Usually, it is not allowed to alter a list, while iterating over it at the same time... Regarding your question: a different approach may be the linq Where() method to only fetch the items from the list that should be removed or updated.
– Nicolas
Nov 26 '18 at 13:45
Wow, it looks like a very complicated way to do something very simple. At the same time, I didn't understand what you are trying to achieve.
– Yeldar Kurmangaliyev
Nov 26 '18 at 13:45
1
@YeldarKurmangaliyev this seem to be a cleanup of a history alike list
– Nicolas
Nov 26 '18 at 13:46
@DanielV, Instead of removing items from list, can we create new list with filtered results? If Yes then we can do it in one line
– Prasad Telkikar
Nov 26 '18 at 13:52
1
@PrasadTelkikar yes, there is no restriction to remove items from the list
– DanielV
Nov 26 '18 at 13:55
|
show 12 more comments
Does your code works without exception? Usually, it is not allowed to alter a list, while iterating over it at the same time... Regarding your question: a different approach may be the linq Where() method to only fetch the items from the list that should be removed or updated.
– Nicolas
Nov 26 '18 at 13:45
Wow, it looks like a very complicated way to do something very simple. At the same time, I didn't understand what you are trying to achieve.
– Yeldar Kurmangaliyev
Nov 26 '18 at 13:45
1
@YeldarKurmangaliyev this seem to be a cleanup of a history alike list
– Nicolas
Nov 26 '18 at 13:46
@DanielV, Instead of removing items from list, can we create new list with filtered results? If Yes then we can do it in one line
– Prasad Telkikar
Nov 26 '18 at 13:52
1
@PrasadTelkikar yes, there is no restriction to remove items from the list
– DanielV
Nov 26 '18 at 13:55
Does your code works without exception? Usually, it is not allowed to alter a list, while iterating over it at the same time... Regarding your question: a different approach may be the linq Where() method to only fetch the items from the list that should be removed or updated.
– Nicolas
Nov 26 '18 at 13:45
Does your code works without exception? Usually, it is not allowed to alter a list, while iterating over it at the same time... Regarding your question: a different approach may be the linq Where() method to only fetch the items from the list that should be removed or updated.
– Nicolas
Nov 26 '18 at 13:45
Wow, it looks like a very complicated way to do something very simple. At the same time, I didn't understand what you are trying to achieve.
– Yeldar Kurmangaliyev
Nov 26 '18 at 13:45
Wow, it looks like a very complicated way to do something very simple. At the same time, I didn't understand what you are trying to achieve.
– Yeldar Kurmangaliyev
Nov 26 '18 at 13:45
1
1
@YeldarKurmangaliyev this seem to be a cleanup of a history alike list
– Nicolas
Nov 26 '18 at 13:46
@YeldarKurmangaliyev this seem to be a cleanup of a history alike list
– Nicolas
Nov 26 '18 at 13:46
@DanielV, Instead of removing items from list, can we create new list with filtered results? If Yes then we can do it in one line
– Prasad Telkikar
Nov 26 '18 at 13:52
@DanielV, Instead of removing items from list, can we create new list with filtered results? If Yes then we can do it in one line
– Prasad Telkikar
Nov 26 '18 at 13:52
1
1
@PrasadTelkikar yes, there is no restriction to remove items from the list
– DanielV
Nov 26 '18 at 13:55
@PrasadTelkikar yes, there is no restriction to remove items from the list
– DanielV
Nov 26 '18 at 13:55
|
show 12 more comments
5 Answers
5
active
oldest
votes
To address the first part of your question : Removing items earlier that a given date.
Kiss is your best friend. either you reasign the list after a filtering or you remove all the item you don't want based on a predicate.
var inputs = new List<CostCenter> {
new CostCenter("a", "70", "2019/11/10"),
new CostCenter("b", "30", "2019/11/10"),
new CostCenter("A", "40", "2018/10/05"),
new CostCenter("B", "60", "2018/10/05"),
new CostCenter("xx","10", "2010/01/01"),
new CostCenter("yy", "90", "2010/01/01"),
new CostCenter("100", "50", "2009/07/03"),
new CostCenter("101", "50", "2009/07/03"),
};
var result1 = inputs.Where(x => x.start > DateTime.Parse("2010/01/01")).ToList();
var result2 = inputs.RemoveAll(x=> x.start <= DateTime.Parse("2010/01/01"));
I may be wrong, but this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, I din't get this part, if row 100 and 101 disapears without fixing the date. Why are the date of xx and yy changed.
– xdtTransform
Nov 26 '18 at 14:02
@xdtTransform your solution doesn't replace "xx" and "yy" with the start date to "2010/11/01"
– DanielV
Nov 26 '18 at 14:26
Not sure what you mean, sorry
– DanielV
Nov 27 '18 at 8:44
@DanielV, My bad I edited a new answer into this post then edited it out and post it as an other answer but system blocked my new answer. or ajax error .. I don't know but the new code was lost in the process. going thought edit history I got it back and push it as a new answer again .
– xdtTransform
Nov 27 '18 at 9:39
add a comment |
First, you need to filter out all outdated items. Then, you can just take the first start, which is the earliest one, and then replace all with _earliestDate.
if (list == null)
throw new ArgumentNullException(...);
// Get rid of unused items and sort:
var actual = list
.Where(item => item.start >= _earliestDate)
.OrderByDescending(item => item.start)
.ToArray();
// If there are no matching items, then return empty array or throw exception
// It depends on your requirements
if (actual.Length == 0)
return actual;
// Take the least date in resulted array...
var earliestInActual = actual[actual.Length - 1];
// ...and replace it with _earliestDate
for (int i = actual.Length - 1; i >= 0; i--)
{
if (actual[i].start != earliestInActual)
break;
item.start = _earliestDate;
}
return actual;
Please, keep in mind that it will change original objects, therefore start dates will e updated in the original list as well.
I think this is the closest to an answer out of all the ones posted,item.start > _earliestDateI think will remove too many results op wants to keep{"yy", 90, "2010/01/01"}
– Matt
Nov 26 '18 at 14:27
@Matt I have updated the answer with>=, thanks :)
– Yeldar Kurmangaliyev
Nov 26 '18 at 15:03
add a comment |
Removing items from a list while using a foreach loop will cause it to lose it's position, you can however use a for loop or just do another loop removing all the flagged ones.
DateTime cutOffDate = DateTime.Parse("2010/11/01");
List<CostCenter> removeList = new List<CostCenter>();
foreach (var item in list.OrderByDescending(x => x.start).ToList())
{
if (item.start <= cutOffDate) {
removeList.Add(item);
}
}
foreach(var remove in removeList)
{
if (list.Contains(remove)) {
list.Remove(remove);
}
}
Not sure I'm following, how will you lose data?
– Matt
Nov 26 '18 at 14:00
Your solution is not replacing the earliest match with the cutOffDate, please take a look at the requirement, I have updated the description to make it more clear.
– DanielV
Nov 26 '18 at 14:46
add a comment |
We can create new filtered list with given criteria
DateTime threshold = new DateTime(2010, 11, 01);
List<CostCenter> result = cc.Where(x => x.start.Date > threshold.Date).ToList();
POC : .netFiddle
Same, this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, can you please elaborate on this
– Prasad Telkikar
Nov 26 '18 at 14:05
@PrasadTelkikar your answer is not addressing the requirement as Yeldar is commenting
– DanielV
Nov 26 '18 at 14:40
add a comment |
For a List where 99% of the elements has to be removed, you will currently iterate throught the whole list to find all those elments and removing them.
Instead of clearing the List select only the part you wan't and stop as soon as you have Date inferior to earliestDate.
With a "TakeWhile" approach just add a flag to know when to edit the element to fix the date.
public static IEnumerable<CostCenter> TakeWhileAndOneAfter
(IEnumerable<CostCenter> source, DateTime splitDate )
{
DateTime? earliestDate = null;
bool earliestFound = false;
foreach (CostCenter element in source)
{
if (!earliestFound && !(element.start > splitDate))
{
earliestFound = true;
earliestDate = element.start;
}
if (earliestFound)
{
if (element.start < earliestDate)
{
break;
}
else
{
element.start = splitDate;
}
}
yield return element;
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53482336%2fremove-items-earlier-than-a-fix-date-and-replace-the-first-occurrence%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
To address the first part of your question : Removing items earlier that a given date.
Kiss is your best friend. either you reasign the list after a filtering or you remove all the item you don't want based on a predicate.
var inputs = new List<CostCenter> {
new CostCenter("a", "70", "2019/11/10"),
new CostCenter("b", "30", "2019/11/10"),
new CostCenter("A", "40", "2018/10/05"),
new CostCenter("B", "60", "2018/10/05"),
new CostCenter("xx","10", "2010/01/01"),
new CostCenter("yy", "90", "2010/01/01"),
new CostCenter("100", "50", "2009/07/03"),
new CostCenter("101", "50", "2009/07/03"),
};
var result1 = inputs.Where(x => x.start > DateTime.Parse("2010/01/01")).ToList();
var result2 = inputs.RemoveAll(x=> x.start <= DateTime.Parse("2010/01/01"));
I may be wrong, but this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, I din't get this part, if row 100 and 101 disapears without fixing the date. Why are the date of xx and yy changed.
– xdtTransform
Nov 26 '18 at 14:02
@xdtTransform your solution doesn't replace "xx" and "yy" with the start date to "2010/11/01"
– DanielV
Nov 26 '18 at 14:26
Not sure what you mean, sorry
– DanielV
Nov 27 '18 at 8:44
@DanielV, My bad I edited a new answer into this post then edited it out and post it as an other answer but system blocked my new answer. or ajax error .. I don't know but the new code was lost in the process. going thought edit history I got it back and push it as a new answer again .
– xdtTransform
Nov 27 '18 at 9:39
add a comment |
To address the first part of your question : Removing items earlier that a given date.
Kiss is your best friend. either you reasign the list after a filtering or you remove all the item you don't want based on a predicate.
var inputs = new List<CostCenter> {
new CostCenter("a", "70", "2019/11/10"),
new CostCenter("b", "30", "2019/11/10"),
new CostCenter("A", "40", "2018/10/05"),
new CostCenter("B", "60", "2018/10/05"),
new CostCenter("xx","10", "2010/01/01"),
new CostCenter("yy", "90", "2010/01/01"),
new CostCenter("100", "50", "2009/07/03"),
new CostCenter("101", "50", "2009/07/03"),
};
var result1 = inputs.Where(x => x.start > DateTime.Parse("2010/01/01")).ToList();
var result2 = inputs.RemoveAll(x=> x.start <= DateTime.Parse("2010/01/01"));
I may be wrong, but this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, I din't get this part, if row 100 and 101 disapears without fixing the date. Why are the date of xx and yy changed.
– xdtTransform
Nov 26 '18 at 14:02
@xdtTransform your solution doesn't replace "xx" and "yy" with the start date to "2010/11/01"
– DanielV
Nov 26 '18 at 14:26
Not sure what you mean, sorry
– DanielV
Nov 27 '18 at 8:44
@DanielV, My bad I edited a new answer into this post then edited it out and post it as an other answer but system blocked my new answer. or ajax error .. I don't know but the new code was lost in the process. going thought edit history I got it back and push it as a new answer again .
– xdtTransform
Nov 27 '18 at 9:39
add a comment |
To address the first part of your question : Removing items earlier that a given date.
Kiss is your best friend. either you reasign the list after a filtering or you remove all the item you don't want based on a predicate.
var inputs = new List<CostCenter> {
new CostCenter("a", "70", "2019/11/10"),
new CostCenter("b", "30", "2019/11/10"),
new CostCenter("A", "40", "2018/10/05"),
new CostCenter("B", "60", "2018/10/05"),
new CostCenter("xx","10", "2010/01/01"),
new CostCenter("yy", "90", "2010/01/01"),
new CostCenter("100", "50", "2009/07/03"),
new CostCenter("101", "50", "2009/07/03"),
};
var result1 = inputs.Where(x => x.start > DateTime.Parse("2010/01/01")).ToList();
var result2 = inputs.RemoveAll(x=> x.start <= DateTime.Parse("2010/01/01"));
To address the first part of your question : Removing items earlier that a given date.
Kiss is your best friend. either you reasign the list after a filtering or you remove all the item you don't want based on a predicate.
var inputs = new List<CostCenter> {
new CostCenter("a", "70", "2019/11/10"),
new CostCenter("b", "30", "2019/11/10"),
new CostCenter("A", "40", "2018/10/05"),
new CostCenter("B", "60", "2018/10/05"),
new CostCenter("xx","10", "2010/01/01"),
new CostCenter("yy", "90", "2010/01/01"),
new CostCenter("100", "50", "2009/07/03"),
new CostCenter("101", "50", "2009/07/03"),
};
var result1 = inputs.Where(x => x.start > DateTime.Parse("2010/01/01")).ToList();
var result2 = inputs.RemoveAll(x=> x.start <= DateTime.Parse("2010/01/01"));
edited Nov 27 '18 at 7:09
answered Nov 26 '18 at 13:54
xdtTransformxdtTransform
433116
433116
I may be wrong, but this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, I din't get this part, if row 100 and 101 disapears without fixing the date. Why are the date of xx and yy changed.
– xdtTransform
Nov 26 '18 at 14:02
@xdtTransform your solution doesn't replace "xx" and "yy" with the start date to "2010/11/01"
– DanielV
Nov 26 '18 at 14:26
Not sure what you mean, sorry
– DanielV
Nov 27 '18 at 8:44
@DanielV, My bad I edited a new answer into this post then edited it out and post it as an other answer but system blocked my new answer. or ajax error .. I don't know but the new code was lost in the process. going thought edit history I got it back and push it as a new answer again .
– xdtTransform
Nov 27 '18 at 9:39
add a comment |
I may be wrong, but this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, I din't get this part, if row 100 and 101 disapears without fixing the date. Why are the date of xx and yy changed.
– xdtTransform
Nov 26 '18 at 14:02
@xdtTransform your solution doesn't replace "xx" and "yy" with the start date to "2010/11/01"
– DanielV
Nov 26 '18 at 14:26
Not sure what you mean, sorry
– DanielV
Nov 27 '18 at 8:44
@DanielV, My bad I edited a new answer into this post then edited it out and post it as an other answer but system blocked my new answer. or ajax error .. I don't know but the new code was lost in the process. going thought edit history I got it back and push it as a new answer again .
– xdtTransform
Nov 27 '18 at 9:39
I may be wrong, but this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
I may be wrong, but this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, I din't get this part, if row 100 and 101 disapears without fixing the date. Why are the date of xx and yy changed.
– xdtTransform
Nov 26 '18 at 14:02
@YeldarKurmangaliyev, I din't get this part, if row 100 and 101 disapears without fixing the date. Why are the date of xx and yy changed.
– xdtTransform
Nov 26 '18 at 14:02
@xdtTransform your solution doesn't replace "xx" and "yy" with the start date to "2010/11/01"
– DanielV
Nov 26 '18 at 14:26
@xdtTransform your solution doesn't replace "xx" and "yy" with the start date to "2010/11/01"
– DanielV
Nov 26 '18 at 14:26
Not sure what you mean, sorry
– DanielV
Nov 27 '18 at 8:44
Not sure what you mean, sorry
– DanielV
Nov 27 '18 at 8:44
@DanielV, My bad I edited a new answer into this post then edited it out and post it as an other answer but system blocked my new answer. or ajax error .. I don't know but the new code was lost in the process. going thought edit history I got it back and push it as a new answer again .
– xdtTransform
Nov 27 '18 at 9:39
@DanielV, My bad I edited a new answer into this post then edited it out and post it as an other answer but system blocked my new answer. or ajax error .. I don't know but the new code was lost in the process. going thought edit history I got it back and push it as a new answer again .
– xdtTransform
Nov 27 '18 at 9:39
add a comment |
First, you need to filter out all outdated items. Then, you can just take the first start, which is the earliest one, and then replace all with _earliestDate.
if (list == null)
throw new ArgumentNullException(...);
// Get rid of unused items and sort:
var actual = list
.Where(item => item.start >= _earliestDate)
.OrderByDescending(item => item.start)
.ToArray();
// If there are no matching items, then return empty array or throw exception
// It depends on your requirements
if (actual.Length == 0)
return actual;
// Take the least date in resulted array...
var earliestInActual = actual[actual.Length - 1];
// ...and replace it with _earliestDate
for (int i = actual.Length - 1; i >= 0; i--)
{
if (actual[i].start != earliestInActual)
break;
item.start = _earliestDate;
}
return actual;
Please, keep in mind that it will change original objects, therefore start dates will e updated in the original list as well.
I think this is the closest to an answer out of all the ones posted,item.start > _earliestDateI think will remove too many results op wants to keep{"yy", 90, "2010/01/01"}
– Matt
Nov 26 '18 at 14:27
@Matt I have updated the answer with>=, thanks :)
– Yeldar Kurmangaliyev
Nov 26 '18 at 15:03
add a comment |
First, you need to filter out all outdated items. Then, you can just take the first start, which is the earliest one, and then replace all with _earliestDate.
if (list == null)
throw new ArgumentNullException(...);
// Get rid of unused items and sort:
var actual = list
.Where(item => item.start >= _earliestDate)
.OrderByDescending(item => item.start)
.ToArray();
// If there are no matching items, then return empty array or throw exception
// It depends on your requirements
if (actual.Length == 0)
return actual;
// Take the least date in resulted array...
var earliestInActual = actual[actual.Length - 1];
// ...and replace it with _earliestDate
for (int i = actual.Length - 1; i >= 0; i--)
{
if (actual[i].start != earliestInActual)
break;
item.start = _earliestDate;
}
return actual;
Please, keep in mind that it will change original objects, therefore start dates will e updated in the original list as well.
I think this is the closest to an answer out of all the ones posted,item.start > _earliestDateI think will remove too many results op wants to keep{"yy", 90, "2010/01/01"}
– Matt
Nov 26 '18 at 14:27
@Matt I have updated the answer with>=, thanks :)
– Yeldar Kurmangaliyev
Nov 26 '18 at 15:03
add a comment |
First, you need to filter out all outdated items. Then, you can just take the first start, which is the earliest one, and then replace all with _earliestDate.
if (list == null)
throw new ArgumentNullException(...);
// Get rid of unused items and sort:
var actual = list
.Where(item => item.start >= _earliestDate)
.OrderByDescending(item => item.start)
.ToArray();
// If there are no matching items, then return empty array or throw exception
// It depends on your requirements
if (actual.Length == 0)
return actual;
// Take the least date in resulted array...
var earliestInActual = actual[actual.Length - 1];
// ...and replace it with _earliestDate
for (int i = actual.Length - 1; i >= 0; i--)
{
if (actual[i].start != earliestInActual)
break;
item.start = _earliestDate;
}
return actual;
Please, keep in mind that it will change original objects, therefore start dates will e updated in the original list as well.
First, you need to filter out all outdated items. Then, you can just take the first start, which is the earliest one, and then replace all with _earliestDate.
if (list == null)
throw new ArgumentNullException(...);
// Get rid of unused items and sort:
var actual = list
.Where(item => item.start >= _earliestDate)
.OrderByDescending(item => item.start)
.ToArray();
// If there are no matching items, then return empty array or throw exception
// It depends on your requirements
if (actual.Length == 0)
return actual;
// Take the least date in resulted array...
var earliestInActual = actual[actual.Length - 1];
// ...and replace it with _earliestDate
for (int i = actual.Length - 1; i >= 0; i--)
{
if (actual[i].start != earliestInActual)
break;
item.start = _earliestDate;
}
return actual;
Please, keep in mind that it will change original objects, therefore start dates will e updated in the original list as well.
edited Nov 26 '18 at 15:03
answered Nov 26 '18 at 13:53
Yeldar KurmangaliyevYeldar Kurmangaliyev
24.9k93966
24.9k93966
I think this is the closest to an answer out of all the ones posted,item.start > _earliestDateI think will remove too many results op wants to keep{"yy", 90, "2010/01/01"}
– Matt
Nov 26 '18 at 14:27
@Matt I have updated the answer with>=, thanks :)
– Yeldar Kurmangaliyev
Nov 26 '18 at 15:03
add a comment |
I think this is the closest to an answer out of all the ones posted,item.start > _earliestDateI think will remove too many results op wants to keep{"yy", 90, "2010/01/01"}
– Matt
Nov 26 '18 at 14:27
@Matt I have updated the answer with>=, thanks :)
– Yeldar Kurmangaliyev
Nov 26 '18 at 15:03
I think this is the closest to an answer out of all the ones posted,
item.start > _earliestDate I think will remove too many results op wants to keep {"yy", 90, "2010/01/01"}– Matt
Nov 26 '18 at 14:27
I think this is the closest to an answer out of all the ones posted,
item.start > _earliestDate I think will remove too many results op wants to keep {"yy", 90, "2010/01/01"}– Matt
Nov 26 '18 at 14:27
@Matt I have updated the answer with
>=, thanks :)– Yeldar Kurmangaliyev
Nov 26 '18 at 15:03
@Matt I have updated the answer with
>=, thanks :)– Yeldar Kurmangaliyev
Nov 26 '18 at 15:03
add a comment |
Removing items from a list while using a foreach loop will cause it to lose it's position, you can however use a for loop or just do another loop removing all the flagged ones.
DateTime cutOffDate = DateTime.Parse("2010/11/01");
List<CostCenter> removeList = new List<CostCenter>();
foreach (var item in list.OrderByDescending(x => x.start).ToList())
{
if (item.start <= cutOffDate) {
removeList.Add(item);
}
}
foreach(var remove in removeList)
{
if (list.Contains(remove)) {
list.Remove(remove);
}
}
Not sure I'm following, how will you lose data?
– Matt
Nov 26 '18 at 14:00
Your solution is not replacing the earliest match with the cutOffDate, please take a look at the requirement, I have updated the description to make it more clear.
– DanielV
Nov 26 '18 at 14:46
add a comment |
Removing items from a list while using a foreach loop will cause it to lose it's position, you can however use a for loop or just do another loop removing all the flagged ones.
DateTime cutOffDate = DateTime.Parse("2010/11/01");
List<CostCenter> removeList = new List<CostCenter>();
foreach (var item in list.OrderByDescending(x => x.start).ToList())
{
if (item.start <= cutOffDate) {
removeList.Add(item);
}
}
foreach(var remove in removeList)
{
if (list.Contains(remove)) {
list.Remove(remove);
}
}
Not sure I'm following, how will you lose data?
– Matt
Nov 26 '18 at 14:00
Your solution is not replacing the earliest match with the cutOffDate, please take a look at the requirement, I have updated the description to make it more clear.
– DanielV
Nov 26 '18 at 14:46
add a comment |
Removing items from a list while using a foreach loop will cause it to lose it's position, you can however use a for loop or just do another loop removing all the flagged ones.
DateTime cutOffDate = DateTime.Parse("2010/11/01");
List<CostCenter> removeList = new List<CostCenter>();
foreach (var item in list.OrderByDescending(x => x.start).ToList())
{
if (item.start <= cutOffDate) {
removeList.Add(item);
}
}
foreach(var remove in removeList)
{
if (list.Contains(remove)) {
list.Remove(remove);
}
}
Removing items from a list while using a foreach loop will cause it to lose it's position, you can however use a for loop or just do another loop removing all the flagged ones.
DateTime cutOffDate = DateTime.Parse("2010/11/01");
List<CostCenter> removeList = new List<CostCenter>();
foreach (var item in list.OrderByDescending(x => x.start).ToList())
{
if (item.start <= cutOffDate) {
removeList.Add(item);
}
}
foreach(var remove in removeList)
{
if (list.Contains(remove)) {
list.Remove(remove);
}
}
answered Nov 26 '18 at 13:54
MattMatt
476210
476210
Not sure I'm following, how will you lose data?
– Matt
Nov 26 '18 at 14:00
Your solution is not replacing the earliest match with the cutOffDate, please take a look at the requirement, I have updated the description to make it more clear.
– DanielV
Nov 26 '18 at 14:46
add a comment |
Not sure I'm following, how will you lose data?
– Matt
Nov 26 '18 at 14:00
Your solution is not replacing the earliest match with the cutOffDate, please take a look at the requirement, I have updated the description to make it more clear.
– DanielV
Nov 26 '18 at 14:46
Not sure I'm following, how will you lose data?
– Matt
Nov 26 '18 at 14:00
Not sure I'm following, how will you lose data?
– Matt
Nov 26 '18 at 14:00
Your solution is not replacing the earliest match with the cutOffDate, please take a look at the requirement, I have updated the description to make it more clear.
– DanielV
Nov 26 '18 at 14:46
Your solution is not replacing the earliest match with the cutOffDate, please take a look at the requirement, I have updated the description to make it more clear.
– DanielV
Nov 26 '18 at 14:46
add a comment |
We can create new filtered list with given criteria
DateTime threshold = new DateTime(2010, 11, 01);
List<CostCenter> result = cc.Where(x => x.start.Date > threshold.Date).ToList();
POC : .netFiddle
Same, this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, can you please elaborate on this
– Prasad Telkikar
Nov 26 '18 at 14:05
@PrasadTelkikar your answer is not addressing the requirement as Yeldar is commenting
– DanielV
Nov 26 '18 at 14:40
add a comment |
We can create new filtered list with given criteria
DateTime threshold = new DateTime(2010, 11, 01);
List<CostCenter> result = cc.Where(x => x.start.Date > threshold.Date).ToList();
POC : .netFiddle
Same, this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, can you please elaborate on this
– Prasad Telkikar
Nov 26 '18 at 14:05
@PrasadTelkikar your answer is not addressing the requirement as Yeldar is commenting
– DanielV
Nov 26 '18 at 14:40
add a comment |
We can create new filtered list with given criteria
DateTime threshold = new DateTime(2010, 11, 01);
List<CostCenter> result = cc.Where(x => x.start.Date > threshold.Date).ToList();
POC : .netFiddle
We can create new filtered list with given criteria
DateTime threshold = new DateTime(2010, 11, 01);
List<CostCenter> result = cc.Where(x => x.start.Date > threshold.Date).ToList();
POC : .netFiddle
answered Nov 26 '18 at 13:56
Prasad TelkikarPrasad Telkikar
1,953419
1,953419
Same, this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, can you please elaborate on this
– Prasad Telkikar
Nov 26 '18 at 14:05
@PrasadTelkikar your answer is not addressing the requirement as Yeldar is commenting
– DanielV
Nov 26 '18 at 14:40
add a comment |
Same, this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, can you please elaborate on this
– Prasad Telkikar
Nov 26 '18 at 14:05
@PrasadTelkikar your answer is not addressing the requirement as Yeldar is commenting
– DanielV
Nov 26 '18 at 14:40
Same, this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
Same, this solution seems to be missing "also this fixed data will replace the earliest match" part.
– Yeldar Kurmangaliyev
Nov 26 '18 at 14:00
@YeldarKurmangaliyev, can you please elaborate on this
– Prasad Telkikar
Nov 26 '18 at 14:05
@YeldarKurmangaliyev, can you please elaborate on this
– Prasad Telkikar
Nov 26 '18 at 14:05
@PrasadTelkikar your answer is not addressing the requirement as Yeldar is commenting
– DanielV
Nov 26 '18 at 14:40
@PrasadTelkikar your answer is not addressing the requirement as Yeldar is commenting
– DanielV
Nov 26 '18 at 14:40
add a comment |
For a List where 99% of the elements has to be removed, you will currently iterate throught the whole list to find all those elments and removing them.
Instead of clearing the List select only the part you wan't and stop as soon as you have Date inferior to earliestDate.
With a "TakeWhile" approach just add a flag to know when to edit the element to fix the date.
public static IEnumerable<CostCenter> TakeWhileAndOneAfter
(IEnumerable<CostCenter> source, DateTime splitDate )
{
DateTime? earliestDate = null;
bool earliestFound = false;
foreach (CostCenter element in source)
{
if (!earliestFound && !(element.start > splitDate))
{
earliestFound = true;
earliestDate = element.start;
}
if (earliestFound)
{
if (element.start < earliestDate)
{
break;
}
else
{
element.start = splitDate;
}
}
yield return element;
}
}
add a comment |
For a List where 99% of the elements has to be removed, you will currently iterate throught the whole list to find all those elments and removing them.
Instead of clearing the List select only the part you wan't and stop as soon as you have Date inferior to earliestDate.
With a "TakeWhile" approach just add a flag to know when to edit the element to fix the date.
public static IEnumerable<CostCenter> TakeWhileAndOneAfter
(IEnumerable<CostCenter> source, DateTime splitDate )
{
DateTime? earliestDate = null;
bool earliestFound = false;
foreach (CostCenter element in source)
{
if (!earliestFound && !(element.start > splitDate))
{
earliestFound = true;
earliestDate = element.start;
}
if (earliestFound)
{
if (element.start < earliestDate)
{
break;
}
else
{
element.start = splitDate;
}
}
yield return element;
}
}
add a comment |
For a List where 99% of the elements has to be removed, you will currently iterate throught the whole list to find all those elments and removing them.
Instead of clearing the List select only the part you wan't and stop as soon as you have Date inferior to earliestDate.
With a "TakeWhile" approach just add a flag to know when to edit the element to fix the date.
public static IEnumerable<CostCenter> TakeWhileAndOneAfter
(IEnumerable<CostCenter> source, DateTime splitDate )
{
DateTime? earliestDate = null;
bool earliestFound = false;
foreach (CostCenter element in source)
{
if (!earliestFound && !(element.start > splitDate))
{
earliestFound = true;
earliestDate = element.start;
}
if (earliestFound)
{
if (element.start < earliestDate)
{
break;
}
else
{
element.start = splitDate;
}
}
yield return element;
}
}
For a List where 99% of the elements has to be removed, you will currently iterate throught the whole list to find all those elments and removing them.
Instead of clearing the List select only the part you wan't and stop as soon as you have Date inferior to earliestDate.
With a "TakeWhile" approach just add a flag to know when to edit the element to fix the date.
public static IEnumerable<CostCenter> TakeWhileAndOneAfter
(IEnumerable<CostCenter> source, DateTime splitDate )
{
DateTime? earliestDate = null;
bool earliestFound = false;
foreach (CostCenter element in source)
{
if (!earliestFound && !(element.start > splitDate))
{
earliestFound = true;
earliestDate = element.start;
}
if (earliestFound)
{
if (element.start < earliestDate)
{
break;
}
else
{
element.start = splitDate;
}
}
yield return element;
}
}
edited Nov 27 '18 at 9:58
answered Nov 27 '18 at 9:35
xdtTransformxdtTransform
433116
433116
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53482336%2fremove-items-earlier-than-a-fix-date-and-replace-the-first-occurrence%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Does your code works without exception? Usually, it is not allowed to alter a list, while iterating over it at the same time... Regarding your question: a different approach may be the linq Where() method to only fetch the items from the list that should be removed or updated.
– Nicolas
Nov 26 '18 at 13:45
Wow, it looks like a very complicated way to do something very simple. At the same time, I didn't understand what you are trying to achieve.
– Yeldar Kurmangaliyev
Nov 26 '18 at 13:45
1
@YeldarKurmangaliyev this seem to be a cleanup of a history alike list
– Nicolas
Nov 26 '18 at 13:46
@DanielV, Instead of removing items from list, can we create new list with filtered results? If Yes then we can do it in one line
– Prasad Telkikar
Nov 26 '18 at 13:52
1
@PrasadTelkikar yes, there is no restriction to remove items from the list
– DanielV
Nov 26 '18 at 13:55