如何过滤一稿阵列基础的,也许-不确定的日期作为串项目的对象的财产?

0

的问题

API返回的结果作为对象超过千值在以下格式:

result = {
  "items": [
            {
              "Name": "abc",
              "CreatedOn": "2017-08-29T15:21:20.000Z",
              "Description": "xyz"
            },
            {
              "Name": "def",
              "CreatedOn": "2021-05-21T15:20:20.000Z",
              "Description": "cvb"
            }
          ]
}

我要过滤器中的项目的对象是超过90天没有必要迭代的所有项目,使用对于环。 换句话说,我想做这样的事情如下但是,这不起作用。

var currentDate = new Date();
var newResult = result.items?.filter(function(i) {
    return ((currentDate - Date.parse(i.CreatedOn)) > 90);
}

根据IDE酒店 CreatedOn 的类型 string | undefined 因此,它投错误:类型的参数 'string | undefined' 是不是转让给参数的类型 'string'. 类型 'undefined' 是不是可转让的类型 'string'.

javascript typescript
2021-11-24 03:43:04
3

最好的答案

2

某个地方在项目中只有 一些像 这样的:

interface Result {
    readonly items: readonly ResultItem[] | null;
}

interface ResultItem {
    readonly Name       : string;
    readonly CreatedOn  : string | undefined;
    readonly Description: string;
}

或者这个(或者它们的变化):

type Result = {
    items?: ResultItem[];
}

interface ResultItem {
    Name       : string;
    CreatedOn? : string;
    Description: string;
}

或者它可以是一个 type 而不是一个 interface (只要确定你从来没有使用 class 来描述java,允许 object 数据不能 class 实例,因为该构造从来没有运行).

此外,你应该能用 camelCase,不 PascalCase为成员的性质。 所使用的名称喜欢 createdOn 而不是的 CreatedOn 在你所产生的手机中。

幸运的是,你不需要改变该类型/接口,只是改变你的稿以 安全 检查 .CreatedOn Date.parse 没有回来 NaN. 像这样:

  • result.items ?? [] 部分是因为你的职位意味着 result.items 是可空的或者,也许-undefined.
  • 注意到当使用 map 有一个 =>风格的功能,可能需要包对象的文字在 () 所以JS引擎不会解释 {} 作为框符。
const result: Result = ...

const currentDate = new Date();

const newResult = (result.items ?? []).filter( e => {
    if( typeof e.CreatedOn === 'string' ) {
        const parsed = Date.parse( e.CreatedOn );
        if( !isNaN( parsed ) ) {
            return ( currentDate - parsed ) > 90;
        }
    }
    return false;
} );

虽然我个人想这样做与一个初始的 filtermap 步骤:

const items       = result.items ?? [];
const currentDate = new Date();

const newResult = items
    .filter( e => typeof e.CreatedOn === 'string' )
    .map( e => ( { ...e, CreatedOn2: Date.parse( e.CreatedOn ) } ) )
    .filter( e => !isNaN( e.CreatedOn2 ) )
    .filter( e => ( currentDate - e.CreatedOn2 ) > 90 ) );

或者简化一步:

const items       = result.items ?? [];
const currentDate = new Date();

const newResult = items
    .filter( e => typeof e.CreatedOn === 'string' )
    .map( e => Object.assign( e, { createdOn2: Date.parse( e.CreatedOn ) )
    .filter( e => !isNaN( e.CreatedOn2 ) && ( currentDate - e.CreatedOn2 ) > 90 );

一个更好的解决方案:

  • 如果你是在控制如何id产生然后你就可以确保某些(或所有)项目特性将始终被设定(并因此从来没有 undefinednull),所以如果你能保证所有3个属性始终设置(永远不会 nullundefined),然后更新类型/接口,以此:

    interface ResultItem {
        readonly name       : string;
        readonly createdOn  : string;
        readonly description: string;
    }
    
    • 注意到 camelCase 属性。
    • 不可改变的数据 是一个巨大的好处,所以确保你的口的特性是所有 readonly所有阵列 readonly T[]和那个性都只注明 ? | null| undefined 作为适当的而不是简单的假设一种或另一种方式。
  • 因此,请确保您使用 strictNullChecks 在你 tsconfig.jsontsc 选择! -其实,只要使用 strict 永远!

  • 还考虑改变式也可与检,从使用一个 string 表示的一个日期(是否有任何gurantees约时?) 是一个本身可读Unix timestamp(在毫秒),这样就可以避免的问题 Date.parse 完全:

例如:

结果。cs:

public class ResultItem
{
    [JsonProperty( "createdOn" )]
    public DateTimeOffset CreatedOn { get; }

    [JsonProperty( "createdOnUnix" )]
    public Int64 CreatedOnUnix => this.CreatedOn.ToUnixTimeMilliseconds();
}

结果。ts:

interface ResultItem {
    readonly createdOn    : string;
    readonly createdOnUnix: number;
}
const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );

const newResult = items.filter( e => new Date( e.createdOnUnix ) < ninetyDaysAgo );

...这样的一个单一的线的工作。


上述可以作出即使是简单作为Unix timestamps只是整数,都直接可比性,所以 new Date() 可以避免内部 filter是这样的:

const ninetyDaysAgo = new Date();
ninetyDaysAgo.setDate( ninetyDaysAgo.getDate() - 90 );
const ninetyDaysAgoUnix = ninetyDaysAgo.getTime();

const newResult = items.filter( e => e.createdOnUnix < ninetyDaysAgoUnix );
2021-11-24 04:21:52
1

假设你已经接口定义的像这样...

interface Item {
  Name: string,
  Description: string,
  CreatedOn?: string // note the optional "?"
}

interface Result {
  items?: Item[] // also optional according to your code
}

和你想要过滤器,用于项超过90天(不包括那些没有 CreatedOn),然后试试这个

interface ItemWithDate extends Omit<Item, "CreatedOn"> {
  CreatedOn?: Date // real dates, so much better than strings
}

const result: Result = { /* whatever */ }

const items: ItemWithDate[] = result.items?.map(({ CreatedOn, ...item }) => ({
  ...item,
  CreatedOn: CreatedOn ? new Date(CreatedOn) : undefined
})) ?? []

const dateThreshold = new Date()
dateThreshold.setDate(dateThreshold.getDate() - 90)

const newItems = items.filter(({ CreatedOn }) =>
  CreatedOn && CreatedOn < dateThreshold)

稿游乐场演示

2021-11-24 04:01:43

请原谅我的无知(这是一个相当大的孔的矿),这是什么 ({ CreatedOn, ...item }) => ({ 做什么呢? 我从来没有见过传播运营商 ... 用一个功能清单参数同时作为对象的文字。
Dai

@戴提取一些名为性质(CreatedOn),并保留在休息 item. 基本上是一个快捷方式 (obj) => { const { a, b, ...rest } = obj; ...
Phil
-1

代码是失踪 ) 的过滤功能

var currentDate = new Date();
var newResult = result.items?.filter(function(i) {
    return ((currentDate - Date.parse(i.CreatedOn)) > 90);
}  ) //<= misss


2021-11-24 04:23:03

你的答案不能解决 tsc's型的错误。
Dai

因为它是目前写的,你的回答是不清楚。 请 编辑 ,以增加额外的详细信息将帮助其他人理解如何解决此问题的要求。 你可以找到更多的信息如何编写很好的答案 在帮助中心.
Community

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................