JavaScript 等效于 C# LINQ 或其他获取数据的方式 [关闭]

Posted

技术标签:

【中文标题】JavaScript 等效于 C# LINQ 或其他获取数据的方式 [关闭]【英文标题】:JavaScript Equivalent to C# LINQ or another way to fetch data [closed] 【发布时间】:2021-02-12 16:28:01 【问题描述】:

我有类似的 JS 数组

var arr = [
   TimeEdit: "2020-10-29T10:45:00.21Z", 
   Date: "2020-10-29T00:00:00", 
   Parameters: [  Id: 1, Value: 1,  Id: 2, Value: 348 ]
   ,
   TimeEdit: "2020-10-29T10:43:52.22Z", 
   Date: "2020-10-29T00:00:00", 
   Parameters: [  Id: 1, Value: 12,  Id: 2, Value: 348 ]
   ,
   TimeEdit: "2020-10-30T10:47:12.33Z", 
   Date: "2020-10-30T00:00:00", 
   Parameters: [  Id: 1, Value: 3,  Id: 2, Value: 2 ]
];

我想从这个数组中选择一个按“TimeEdit”排序的唯一“日期”数据,以便在输出时我可以得到这个数组

[
   TimeEdit: "2020-10-29T10:45:00.21Z", 
   Date: "2020-10-29T00:00:00", 
   Parameters: [  Id: 1, Value: 1,  Id: 2, Value: 348 ]
   ,
   TimeEdit: "2020-10-30T10:47:12.33Z", 
   Date: "2020-10-30T00:00:00", 
   Parameters: [  Id: 1, Value: 3,  Id: 2, Value: 2 ]
];

在 C# 代码中,我会这样做:

var dates = arr.Select(r => r.Date).Distinct().ToList();
foreach (var date in dates)

   WorkLog log = arr.Where(r => r.Datetime == date).OrderByDescending(r => r.TimeEdit).FirstOrDefault();
   //to do some stuff here

那么在 JS 中最好的方法是什么?

【问题讨论】:

你用javascript试过什么了吗? 【参考方案1】:

JavaScript 有许多内置函数,可帮助您以 linq-ish 方式处理数组。像map(相当于Select)和filter(相当于Where)这样的函数浮现在脑海。查看 docs 的 MDN。

尽管这些可能非常有用,但使用另一个库来处理数组或对象也会很有用。根据我的经验,lodash 对于操作数组非常方便。它有一个 chain 方法,您可以使用它以非常类似于 linq 的方式表达操作。

const dates = _.chain(arr).map(r => r.Date).uniq().value();

dates.forEach(date => 
  const log = _.chain(arr)
    .filter(r => r.Datetime === date)
    .sortBy(r => r.TimeEdit)
    .reverse()
    .head();

  //to do some stuff here
);

【讨论】:

【参考方案2】:

您可以使用一些自己的函数来模仿这种行为,用于分组、排序、排序和获取每个组的第一项。为了绑定在一起,你还需要一个管道函数。

const
    pipe = (...functions) => input => functions.reduce((acc, fn) => fn(acc), input),
    groupBy = key => array => array.reduce((r, o) => 
        var fn = typeof key === 'function' ? key : o => o[key],
            temp = r.find(([p]) => fn(o) === fn(p));
        if (temp) temp.push(o);
        else r.push([o]);
        return r;
    , []),
    order = (...keys) => array => array.sort((a, b) => 
        var result;
        keys.some(k => result = a[k] > b[k] || -(a[k] < b[k]));
        return result
    ),
    select = fn => array => array.map(fn),
    first = array => array[0],
    data = [ TimeEdit: "2020-10-29T10:45:00.21Z", Date: "2020-10-29T00:00:00", Parameters: [ Id: 1, Value: 1 ,  Id: 2, Value: 348 ] ,  TimeEdit: "2020-10-29T10:43:52.22Z", Date: "2020-10-29T00:00:00", Parameters: [ Id: 1, Value: 12 ,  Id: 2, Value: 348 ] ,  TimeEdit: "2020-10-30T10:47:12.33Z", Date: "2020-10-30T00:00:00", Parameters: [ Id: 1, Value: 3 ,  Id: 2, Value: 2 ] ],
    result = pipe(
        groupBy('Date'),
        select(
            pipe(
                order('TimeEdit'),
                first
            )
        )
    )(data);

console.log(result);
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

以上是关于JavaScript 等效于 C# LINQ 或其他获取数据的方式 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Java 等效于 C# Linq 中的 Where 子句

JavaScript/jQuery 等效于 LINQ Any()

等效于链式 LINQ 扩展方法调用中的 'let' 关键字的代码

等效于链式 LINQ 扩展方法调用中的 'let' 关键字的代码

C# 中的 Jaxb 等效项

C# 中的 Jaxb 等效项