Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Groovy-从复杂嵌套映射聚合和建模数据_List_Dictionary_Groovy - Fatal编程技术网

List Groovy-从复杂嵌套映射聚合和建模数据

List Groovy-从复杂嵌套映射聚合和建模数据,list,dictionary,groovy,List,Dictionary,Groovy,下面的代码片段中显示了groovy中的数据: def productAvailability = [ [id: 1, startDate: "2014-12-22", endDate: "2015-01-02", storeId: 1, productId: 1, categoryId: 1], [id: 4, startDate: "2014-12-24", endDate: "2015-01-08", storeId: 2, productId: 1, categoryId: 1],

下面的代码片段中显示了groovy中的数据:

def productAvailability = [
  [id: 1, startDate: "2014-12-22", endDate: "2015-01-02", storeId: 1, productId: 1, categoryId: 1],
  [id: 4, startDate: "2014-12-24", endDate: "2015-01-08", storeId: 2, productId: 1, categoryId: 1],
  [id: 8, startDate: "2014-12-25", endDate: "2015-01-01", storeId: 2, productId: 3, categoryId: 1],
  [id: 9, startDate: "2014-12-22", endDate: "2015-01-02", storeId: 1, productId: 3, categoryId: 1],
  [id: 10, startDate: "2015-01-10", endDate: "2015-01-21", storeId: 1, productId: 1, categoryId: 1]
];
目标是获得如下结果:

产品统计

Product Id: 1 | Availability Index: 15 + 11 + 11 = 37.
   Longest Available Products (Sort By Past Start Date *first* then, Store Id): 
       1. "2014-12-24" to "2015-01-08" in store id 2. (15 days)
       2. "2014-12-22" to "2015-01-02" in store id 1. (11 days)
       3. "2015-01-10" to "2015-01-21" in store id 1. (11 days)
Product Id: 3 | Availability Index: 7 + 11 = 18.
   Longest Available Products (Sort By Past Start Date *first* then, Store Id): 
       1. "2014-12-22" to "2015-01-02" in store id 1. (11 days)
       2. "2014-12-25" to "2015-01-01" in store id 2. (7 days)
Store Id: 1 | Availability Index: 11 + 11 + 11 = 33.
   Most Available Product (sort by most available product, then sort by product id):
       1. Product Id: 3 on ["2014-12-22" to "2015-01-02"] (11 days)
       2. Product Id: 1 on ["2014-12-22" to "2015-01-02", "2015-01-10" to "2015-01-21"] (11 days)
Store Id: 2 | Availability Index: 15 + 7 = 22.
   Most Available Product (sort by most available product, then sort by product id):
       1. Product Id: 1 on ["2014-12-24" to "2015-01-08"] (15 days)
       2. Product Id: 3 on ["2014-12-25" to "2015-01-01"] (7 days)

Total Availability Index: 37 + 18 or 33 + 22 = 55.
商店统计数据

Product Id: 1 | Availability Index: 15 + 11 + 11 = 37.
   Longest Available Products (Sort By Past Start Date *first* then, Store Id): 
       1. "2014-12-24" to "2015-01-08" in store id 2. (15 days)
       2. "2014-12-22" to "2015-01-02" in store id 1. (11 days)
       3. "2015-01-10" to "2015-01-21" in store id 1. (11 days)
Product Id: 3 | Availability Index: 7 + 11 = 18.
   Longest Available Products (Sort By Past Start Date *first* then, Store Id): 
       1. "2014-12-22" to "2015-01-02" in store id 1. (11 days)
       2. "2014-12-25" to "2015-01-01" in store id 2. (7 days)
Store Id: 1 | Availability Index: 11 + 11 + 11 = 33.
   Most Available Product (sort by most available product, then sort by product id):
       1. Product Id: 3 on ["2014-12-22" to "2015-01-02"] (11 days)
       2. Product Id: 1 on ["2014-12-22" to "2015-01-02", "2015-01-10" to "2015-01-21"] (11 days)
Store Id: 2 | Availability Index: 15 + 7 = 22.
   Most Available Product (sort by most available product, then sort by product id):
       1. Product Id: 1 on ["2014-12-24" to "2015-01-08"] (15 days)
       2. Product Id: 3 on ["2014-12-25" to "2015-01-01"] (7 days)

Total Availability Index: 37 + 18 or 33 + 22 = 55.
上面打印的结果是产品统计和商店统计。 我会寻求优化,高效,易于理解的解决方案来打印上述结果

我试图从上述数据中获得结果:

// productAvailability => see the declaration variable above in the beginning of question!
List aggregateDates = productAvailability.collect({[
    storeId: it.storeId,
    productId: it.productId,
    availabilityIndex: Date.parse("YYYY-MM-dd", it.endDate) - Date.parse("YYYY-MM-dd", it.startDate) 
]});
println "Total Availability Index: " + aggregateDates.clone().sum({ it.availabilityIndex });
println "Total Products: " +  aggregateDates.clone().unique({ it.productId }).count({ it.productId });
println "Total Stores: " + aggregateDates.clone().unique({ it.storeId }).count({ it.storeId });
println "Average Availability Index: " + aggregateDates.clone().sum({ it.availabilityIndex }) / aggregateDates.size();
正如您在上面的代码片段中所看到的,我可以很容易地获得聚合总和AVG,并计算productAvailability数据中有多少产品和存储。然而,我很难根据产品和门店使用日期范围获得可用性,以实现上述目标

请参阅下面使用日期范围的代码

def dailyDatesAvailability = [:] as Map<Date, Integer>;
def dailyStoresAvailability = [:].withDefault {0} as Map<Integer, Integer>;
def dailyProductsAvailability  = [:].withDefault {0} as Map<Integer, Integer>;
(Date.parse("YYYY-MM-dd", "2014-12-01")).upto((Date.parse("YYYY-MM-dd", "2015-01-30"))) { Date runningDate ->
        dailyDatesAvailability[runningDate] = 0;
        productAvailability.each({ _availability ->
            def _startDate = Date.parse("YYYY-MM-dd", _availability.startDate);
            def _endDate = Date.parse("YYYY-MM-dd", _availability.endDate);
            if (_startDate <= runningDate && _endDate >= runningDate) {
                dailyDatesAvailability[runningDate]++;
                dailyProductsAvailability[_availability.productId]++;
                dailyStoresAvailability[_availability.storeId]++;
            }

         // Do something here to get the MOST available PRODUCT in a STORE with date ranges
        });
       /// or do something here....?
    }
def dailydatesavaailability=[:]作为映射;
def dailyStoresAvailability=[:];
def dailyProductsAvailability=[:],默认为映射{0};
(日期解析(“YYYY-MM-dd”,“2014-12-01”))。截至(日期解析(“YYYY-MM-dd”,“2015-01-30”){日期运行日期->
dailyDatesAvailability[runningDate]=0;
productAvailability.each({u availability->
def _startDate=Date.parse(“YYYY-MM-dd”,“u availability.startDate”);
def _endDate=Date.parse(“YYYY-MM-dd”,_availability.endDate);
如果(_startDate=运行日期){
dailyDatesAvailability[运行日期]+;
dailyProductsAvailability[_availability.productId]++;
dailyStoresAvailability[_availability.storeId]++;
}
//在这里做点什么,在有日期范围的商店里买到最畅销的产品
});
///或者在这里做点什么。。。。?
}

使用Groovy打印上述目标的最佳方法是什么?请分享代码片段以进行测试。

对此很感兴趣,并提出:

List<Range> simplify( List<Range> ranges ) {
  ranges.drop( 1 ).inject( ranges.take( 1 ) ) { r, curr ->
    // Find an overlapping range
    def ov = r.find { curr.from <= it.to && curr.to >= it.from }
    if( ov ) {
      ov.from = [ curr.from, ov.from ].min()
      ov.to   = [ curr.to, ov.to ].max()
      simplify( r )
    }
    else {
      r << curr
    }
  }
}

def manipulate(data, primary, secondary) {
    data.groupBy { it."$primary" }
        .collect { id, vals ->
            def joined = vals.collect { it ->
                [ id: it.id,
                  range: Date.parse('yyyy-MM-dd', it.startDate)..Date.parse('yyyy-MM-dd', it.endDate),
                  key: secondary,
                  value: it."$secondary" ]
            }.groupBy { it.value }
             .collectMany { sid, ran -> simplify(ran.range).collect { [key: secondary, value: sid, range:it, days:(it.to - it.from)] } }
             .sort { a, b -> b.days <=> a.days ?: a.value - b.value }
            [name:primary, id:id, data:joined]
        }
}

def dump(data) {
    data.collect { a ->
        def sum = a.data.days.sum()
        println "$a.name: $a.id | availability index ${a.data.days.join(' + ')} = ${sum}"
        a.data.eachWithIndex { row, idx ->
            println "    ${idx+1}. ${row.range.from.format('yyyy-MM-dd')} to ${row.range.to.format('yyyy-MM-dd')} in $row.key $row.value ($row.days days)"
        }
        sum
    }
}

def productAvailability = [
  [id: 1, startDate: "2014-12-22", endDate: "2015-01-02", storeId: 1, productId: 1, categoryId: 1],
  [id: 4, startDate: "2014-12-24", endDate: "2015-01-08", storeId: 2, productId: 1, categoryId: 1],
  [id: 8, startDate: "2014-12-25", endDate: "2015-01-01", storeId: 2, productId: 3, categoryId: 1],
  [id: 9, startDate: "2014-12-22", endDate: "2015-01-02", storeId: 1, productId: 3, categoryId: 1],
  [id: 10, startDate: "2015-01-10", endDate: "2015-01-21", storeId: 1, productId: 1, categoryId: 1]
];

def p = dump(manipulate(productAvailability, 'productId', 'storeId'))
println ''
def s = dump(manipulate(productAvailability, 'storeId', 'productId'))
println ''
println "Total Availability Index: ${p.join(' + ')} or ${s.join(' + ')} = ${[p.sum(), s.sum()].max()}"

请共享代码段以便能够测试。。感谢您使用“为我做编码工作”服务。目前所有高薪开发者都很忙。你能分享一下你迄今为止的一些尝试吗?@cfrick我更新了问题并添加了我尝试的代码片段。请参阅..@cfrick我更新了
aggregateDates
variable中日期操作的代码段在示例产品统计输出中id为
10
的行发生了什么情况?@tim_yates很好!它应该包含在门店id 1中编号2“2014-12-22”到“2015-01-02”之后。此外,产品id 3还应该有额外的输出。请查看更新。我刚刚更新了产品统计输出,并修复了产品统计输出中的错误日期。请给我时间回顾一下,我昨天通过对开始日期和结束日期之间的差异进行排序,然后按商店和产品进行分组(与您的概念相同)解决了主要问题-我认为这比您的简单得多。我将稍后发布解决方案。但是你的解决方案给出了目标的作用。再次感谢蒂姆的努力,谢谢你!