如何从另一个数组

时间:2017-10-24 17:13:18

标签: powershell

背景:

我工作的学校的学生院长要求我将LMS的每日出勤率和课堂出勤率输入我们的SIS。这很容易,直到我意识到存在交叉污染。例如,如果约翰的父母通过电子邮件让学校知道约翰生病了,请于2017年10月24日生病。院长标记约翰当天缺席,然后他的老师在他的每个班级都标记他缺席。因此,约翰在10/24/2017每日出勤记录和当天错过的每个班级有6个班级缺勤记录。

他们不会改变他们的流程,所以我需要一种方法来删除导入文件中的Class缺席,以便在同一天也有Daily Absences的学生。

问题:

我有两个PSObject数组包含具有不同属性的对象。

每日出勤数组中的对象$dailyRecords都具有StudentIDDateTypeDescription的属性。

班级出勤数组$classRecords的对象具有与第一个对象相同的属性,另外还有CourseIDSectionNo

我尝试了几种方法从$classRecords数组中删除额外的类记录:

  1. $classRecords | Where-Object { $_.Date, $_.StudentID -notin $dailyRecords},基于this answer,但这给了我所有〜1600个班级记录。
  2. 我尝试了以下内容,基于this answer,但没有结果(我认为)数组中的对象引用了不同的类型......?不确定。 (我刚刚使用了以下内容,我没有包含foreach部分。也许这就是问题......今晚我会尝试并更新。)

    Compare-Object $classRecords $dailyRecords |
        Where-Object {$_.SideIndicator -ne "=="} | 
        Select-Object -ExpandProperty InputObject
    
  3. 我也试过#2的变种:

    Compare-Object $classRecords $dailyRecords -Property Date, StudentID |
        Where-Object {$_.SideIndicator -ne "=="}
    # I had to remove the last line, as InputObject was no longer defined. 
    

    但是这导致我失去了我需要的所有其他属性。

  4. This answer会产生最接近我想要做的事情,但我无法弄清楚如何根据自己的需要对其进行修改。

  5. 如何从课堂出勤中删除重复数据,而不会丢失有关对象本身的任何信息?

4 个答案:

答案 0 :(得分:1)

我会做这样的事情:

$dailyRecords = @(
[PSCustomObject]@{StudentId='1'; Date='10/22/2017'; Type='type data'; Description='desc data'}
[PSCustomObject]@{StudentId='1'; Date='10/23/2017'; Type='type data'; Description='desc data'}
[PSCustomObject]@{StudentId='1'; Date='10/24/2017'; Type='type data'; Description='desc data'}
[PSCustomObject]@{StudentId='2'; Date='10/24/2017'; Type='type data'; Description='desc data'}
[PSCustomObject]@{StudentId='3'; Date='10/23/2017'; Type='type data'; Description='desc data'}
[PSCustomObject]@{StudentId='3'; Date='10/24/2017'; Type='type data'; Description='desc data'}
)

$classRecords = @(
[PSCustomObject]@{StudentId='1'; Date='10/19/2017'; Type='type data'; Description='desc data'; CourseId='1'; SectionNum='1'}
[PSCustomObject]@{StudentId='1'; Date='10/23/2017'; Type='type data'; Description='desc data'; CourseId='2'; SectionNum='2'}
[PSCustomObject]@{StudentId='1'; Date='10/24/2017'; Type='type data'; Description='desc data'; CourseId='3'; SectionNum='3'}
[PSCustomObject]@{StudentId='4'; Date='10/24/2017'; Type='type data'; Description='desc data'; CourseId='1'; SectionNum='1'}
)

$attendanceRecords = @{}

foreach ($record in $dailyRecords)
{
    $key = $record.StudentId + ';' + $record.Date
    $attendanceRecords.Add($key, $record)
}

foreach ($record in $classRecords)
{
    $key = $record.StudentId + ';' + $record.Date
    if (-not $attendanceRecords.ContainsKey($key))
    {
        $tempRecord = [PSCustomObject]($record | Select-Object StudentId, Date, Type, Description)
        $attendanceRecords.Add($key, $tempRecord)
    }
}

$attendanceRecords.Values | Sort -Property StudentId, Date | ft

并提供输出:

StudentId Date       Type      Description
--------- ----       ----      -----------
1         10/19/2017 type data desc data  
1         10/22/2017 type data desc data  
1         10/23/2017 type data desc data  
1         10/24/2017 type data desc data  
2         10/24/2017 type data desc data  
3         10/23/2017 type data desc data  
3         10/24/2017 type data desc data  
4         10/24/2017 type data desc data

这是所有每日和每个类别,根据您的原始要求,它们不在每日。

答案 1 :(得分:0)

尝试这样的事情:

$classrecords=@(
[pscustomobject]@{Date='2017-10-24';StudentID=1}, 
[pscustomobject]@{Date='2017-10-25';StudentID=2},
[pscustomobject]@{Date='2017-10-26';StudentID=3}
)


$dailyRecords=@(
[pscustomobject]@{Date='2017-10-24';StudentID=1}, 
[pscustomobject]@{Date='2017-10-23';StudentID=2},
[pscustomobject]@{Date='2017-10-26';StudentID=5}
)


$classrecords | % {$current=$_; $dailyRecords | % { if ($_.Date -eq $current.Date -and $_.StudentID -eq $current.StudentID) {$current}}} 

答案 2 :(得分:0)

$ret = @()
foreach($classRecord in $classRecords)
{
    foreach($dailyRecord in $dailyRecords)
    {
        if($classRecord.CourseID -eq $dailyRecord.CourseID) # modify this to match your conditions
        {
          $obj = New-Object PsObject
          foreach($classProp in $classRecord.PsObject.Properties) # do this loop for $dailyRecord if you want those properties as well
          {
            $obj | Add-Member -NotePropertyName $prop.Name -NotePropertyValue $prop.Value
          }
          $ret += $obj
        }
    }
}

# output the array
$ret

之后,您可能需要从$ret

中过滤出欺骗行为

答案 3 :(得分:0)

$classRecords | Where {$c = $_; $dailyRecords | Where {$_.StudentID -ne $c.StudentID -and $_.Date -ne $c.Date}}