用唯一标识符替换数组中的元素

时间:2019-11-29 15:09:42

标签: typescript

我有一个dailyEntries数组。 DailyEntry具有唯一的标识符id。我有一个外部dailyEntry,并想用外部的dailyEntry替换阵列中的this.dailyEntries = this.dailyEntries.map(function (dailyEntry) { if (dailyEntry.id === externalEntry.id) { dailyEntry = externalEntry; } return dailyEntry; });

我这样做是:

this.dailyEntries = this.dailyEntries.map(dailyEntry => dailyEntry.id === entry.id ? entry : dailyEntry);

有更好的方法吗?对于简单的替换来说,这似乎有点太多代码。

编辑: 我想我可以在一行中做同样的事情:

'CREATION OF COUNTER FOR MONTHS OF 30 DAYS
    '------------------------------------------------------------------------------------
Set rs_Results = Server.CreateObject("ADODB.Recordset") -(creation of recordset for opening sql query)

    If month_num = 4 Or month_num = 6 month_num = 9 Or month_num = 11 Then -(checks the specific months with 30 days)

    For day_counter=1 To 30 -(creates a counter for days from 1 to 30 since is the case for months 

of 30 days only)

        search_date = cDate(day_counter &"-"& month_num &"-"& year_num) -(inserts the day counter along with the
 month and year counter separating them by "-" making it a valid date after the conversion)

        converted_date= Clng(search_date) -(converts the date of the variable 'search_date' to numbers)
    strSQL_CIP_Date="SELECT * FROM data_storage WHERE creation_date=" & converted_date 

    'cn_body.execute (strSQL_CIP_Date) -(when using this method on the portion of page that shows the results it throws 
an error which is: 'ADODB.Recordset error '800a0e78' Operation not allowed if the object is closed.', in this case the 
query is executed the times it should, but the results aren't shown because of the mentioned error)

        rs_Results.open strSQL_CIP_Date,cn_body,1,1 

(cn_body is the string connection which is stored into another page, 
    what i'm doing here is opening the sql query using the recordset which is the method i used for other queries without bigger issues,
    but for some reason here it is not working, only runs 2 times then it appears this error: 
    'ADODB.Recordset error '800a0e79'

'Operation not allowed if the object is open')

        response.write day_counter & " " & strSQL_CIP_Date & "<br><br><br><br>" 
-(prints the query with the converted date to ask to the database)
    Next
End If

但是还有更好的解决方案吗?

1 个答案:

答案 0 :(得分:4)

  

但是还有更好的解决方案吗?

不是。代码可以更简洁(编辑:您也编辑了问题以说得这么清楚)

this.dailyEntries = this.dailyEntries.map(dailyEntry => dailyEntry.id === externalEntry.id ? externalEntry : dailyEntry);

或者在这种操作中,通常使用e作为参数,因为它是一个非常小的函数(e代表“元素”):

this.dailyEntries = this.dailyEntries.map(e => e.id === externalEntry.id ? externalEntry : e);

另一种方法是findIndex,但它似乎不如您的map解决方案好:

const index = this.dailyEntries.findIndex(({id}) => id === externalEntry.id);
this.dailyEntries[index] = externalEntry;

(使用解构从输入参数中提取idmap回调中。)

它们之间的最大区别是map解决方案创建了一个新数组,但是findIndex解决方案更新了现有数组(其优点是:找到条目时会循环;但是缺点是有时您希望将对象[包括数组]视为不可变的。

对于此操作,您始终可以为自己提供可重用的功能:

function replaceInArray(array, propName, newEntry) {
    return array.map(e => e[propName] === newEntry[propName] ? newEntry : e);
}

然后

this.dailyEntries = replaceInArray(this.dailyEntries, "id", externalEntry);

以上所有假设(如您当前的代码)都假定该条目确实存在于数组中。如果该条目可能不是位于数组中,则这会降低map的吸引力,并建议使用findIndex是更好的方法:

const index = this.dailyEntries.findIndex(({id}) => id === externalEntry.id);
if (index === -1) {
    this.dailyEntries.push(externalEntry);
} else {
    this.dailyEntries[index] = externalEntry;
}

最后但并非最不重要的一点:如果要在多个位置使用其id来引用该条目,则数组可能不是正确的数据结构(但也可能是正确的数据结构,这取决于您还需要做什么)重新做)。例如,您可以将它们保留在Map(或对象)中。然后替换它(或添加它(如果不存在的话))非常简单:

this.dailyEntries.set(externalEntry.id, externalEntry);

如果您需要一个条目数组(按它们添加的顺序),则可以从Map的{​​{1}}方法的迭代器中获取它:values (或者,如果您本身不需要 array ,则直接使用Iterable)。

相关问题