2016-12-09 21 views
2

私はこのオブジェクトの配列を持っています。いくつかの条件に従って、特定の科目に費やす時間を計算したいと思います。配列内のオブジェクトの合計を見つける方法

私は被験者を特定するためのコードを持っています: しかし、私はそれらの特定の被験者の分の合計を見つけるのに苦労しています。

あなたが行うことができます
$scope.total = 0; 
$scope.found = []; 

angular.forEach($scope.all, function(value, index) { 
    angular.forEach(value.time, function (item, index) { 

     $scope.total += value.time[index].minutes; 

     if (item.subject === "english" || item.subject === "maths"  
     && $scope.total === 150) { 
      $scope.found.push(value); 
     } 
    }); 
}); 
"students": [ 
    { 
     "id": 1, 
     "name": "Natalie", 
     "gender": "female", 
     "time": [ 
      { 
       "subject": "geography", 
       "minutes": 100 
      },{ 
       "subject": "english", 
       "minutes": 20 
      },{ 
       "subject": "maths", 
       "minutes": 760 
      } 
     ] 
    },{ 
     "id": 2, 
     "name": "John", 
     "gender": "male", 
     "time": [ 
      { 
       "subject": "spanish", 
       "minutes": 450 
      },{ 
       "subject": "maths", 
       "minutes": 900 
      },{ 
       "subject": "geography", 
       "minutes": 200 
      } 
     ] 
    } 
] 
+0

あなたは有効なJavaScriptを投稿しませんでした。投稿したコードを実行しようとすると、エラーが発生します。 –

+1

あなたは何を受け取っていると思っていますか? –

+0

私は、被験者の数学や英語を勉強している学生を出力して150分を過ごしたことが分かりましたが、私のコードでは正しい学生に数学と英語を取るが、合計は完全に間違っています。 – Useer

答えて

1

var students = [{"id": 1,"name": "Natalie","gender": "female","time": [{"subject": "geography","minutes": 100}, {"subject": "english","minutes": 20}, {"subject": "maths","minutes": 760}]}, {"id": 2,"name": "John","gender": "male","time": [{"subject": "spanish","minutes": 450}, {"subject": "maths","minutes": 900}, {"subject": "geography","minutes": 200}]}], 
 
    getTotalMinutes = function (time) { 
 
     return time 
 
     .map(function (s) { 
 
      return s.minutes; 
 
     }) 
 
     .reduce(function (a, b) { 
 
      return a + b; 
 
     }, 0); 
 
    }, 
 
    result = students.map(function (student) { 
 
     return { 
 
     [student.name]: getTotalMinutes(student.time) 
 
     }; 
 
    }); 
 

 
console.log(result);

+0

@Useer質問は、合計時間の合計を得ることです? –

+0

ありがとう、それも素晴らしいです。 – Useer

2

これはJavscript reducefilterの機能を利用するための良い候補です。

Filterは配列の各エントリに対して関数を実行し、その関数が返す値がtrueの新しい配列を返します。

Reduceは配列内の各エントリを繰り返し処理しながら合計値を保持します。配列を単一の値に「減らす」ために使用されていると言えるでしょう。これはここでやりたいことです。ここで

students変数は、学生のあなたの配列が含まれていることを考えると、例です:

// We'll match against this variable 
 
var desiredSubject = "maths" 
 

 
// First, we iterate over each student in the array 
 
var time = students.reduce(function(previousTime, student) { 
 
    // Inside the array is another array, so we want to 
 
    // reduce that one after filtering it to match our subject 
 
    var subjectTime = student.time.filter(function(subject) { 
 
    // Keep only subjects that match ours 
 
    return subject.subject == desiredSubject; 
 
    }).reduce(function(previousMinutes, subject) { 
 
    // Then sum up the minutes from each one 
 
    return previousMinutes + subject.minutes; 
 
    }, 0); // Our initial sum is 0 
 
    // Sum up each student's minutes 
 
    return previousTime + subjectTime; 
 
}, 0); // Again, with an initial sum of 0

reduce機能を備えた「落とし穴」の共通はあなたを持っていることであることに留意してください開始値の後にreduce関数。そこに置くことを忘れるのはとても簡単です。

+0

大変ありがとうございます、それは間違いなく正しい方向に私を導きます:-) – Useer

+0

これをAngularで追加します。このようなものを 'service'に置くのがよいでしょうコードに使用されるか、それがユーザに表示される場合には 'フィルタ'になります。そうすれば、スコープ内のコード量を減らすことができます(フィルタの場合)。 '$ scope.students'配列が変更された場合、ビューは自動的に更新されます。 –

1

あなたはそれぞれの時間の合計の被験者のコレクションを生成するためにstudents.reduceを使用することができます。

var students = [{ 
 
    "id": 1, 
 
    "name": "Natalie", 
 
    "gender": "female", 
 
    "time": [{ 
 
     "subject": "geography", 
 
     "minutes": 100 
 
    }, { 
 
     "subject": "english", 
 
     "minutes": 20 
 
    }, { 
 
     "subject": "maths", 
 
     "minutes": 760 
 
    }] 
 
}, { 
 
    "id": 2, 
 
    "name": "John", 
 
    "gender": "male", 
 
    "time": [{ 
 
     "subject": "spanish", 
 
     "minutes": 450 
 
    }, { 
 
     "subject": "maths", 
 
     "minutes": 900 
 
    }, { 
 
     "subject": "geography", 
 
     "minutes": 200 
 
    }] 
 
}] 
 

 
var subjectTimes = students.reduce(function(result, student) { 
 
    student.time.reduce(function(prev, time) { 
 
     if (time.subject in result) 
 
      result[time.subject] += time.minutes; 
 
     else 
 
      result[time.subject] = time.minutes; 
 
    }, {}) 
 
    return result; 
 
}, {}); 
 

 
console.log(subjectTimes);

関連する問題