سؤال

هدفي هو الحصول على متوسط مرجح من جدول واحد ، على أساس آخر الجداول المفتاح الأساسي.

البيانات المثال:

جدول1

Key     WEIGHTED_AVERAGE

0200    0

Table2

ForeignKey    Length    Value
0200          105       52
0200          105       60
0200          105       54
0200          105       -1
0200          47        55

أنا بحاجة للحصول على متوسط مرجح على أساس طول قطعة و لا تحتاج إلى تجاهل قيم -1.أنا أعرف كيفية القيام بذلك في SQL, ولكن هدفي هو أن تفعل هذا في LINQ.يبدو شيئا من هذا القبيل في SQL:

SELECT Sum(t2.Value*t2.Length)/Sum(t2.Length) AS WEIGHTED_AVERAGE
FROM Table1 t1, Table2 t2
WHERE t2.Value <> -1
AND t2.ForeignKey = t1.Key;

أنا لا تزال جديدة جدا أن LINQ, وجود صعوبة في معرفة كيف سيترجم هذا.نتيجة المتوسط المرجح أن يخرج إلى حوالي 55.3.شكرا لك.

هل كانت مفيدة؟

المحلول

أنا أفعل هذا يكفي أنني خلقت امتداد طريقة LINQ.

public static double WeightedAverage<T>(this IEnumerable<T> records, Func<T, double> value, Func<T, double> weight)
{
    double weightedValueSum = records.Sum(x => value(x) * weight(x));
    double weightSum = records.Sum(x => weight(x));

    if (weightSum != 0)
        return weightedValueSum / weightSum;
    else
        throw new DivideByZeroException("Your message here");
}

بعد حصولك على مجموعة فرعية من بيانات الإتصال يبدو مثل هذا.

double weightedAverage = records.WeightedAverage(x => x.Value, x => x.Length);

أصبح هذا مفيد للغاية لأنه يمكن الحصول على متوسط مرجح من أي مجموعة من البيانات استنادا إلى حقل آخر في نفس السجل.

التحديث

أنا الآن التحقق من قسمة صفر ورمي أكثر تفصيلا استثناء بدلا من العودة 0.تتيح للمستخدم التقاط استثناء والتعامل معها حسب الحاجة.

نصائح أخرى

إذا كنت على يقين من أن لكل الأجنبية الرئيسية في Table2 هناك سجل المقابلة في جدول1 ثم يمكنك تجنب الانضمام إلى جعل مجرد الفريق من قبل.

في هذه الحالة ، LINQ الاستعلام مثل هذا:

IEnumerable<int> wheighted_averages =
    from record in Table2
    where record.PCR != -1
    group record by record.ForeignKey into bucket
    select bucket.Sum(record => record.PCR * record.Length) / 
        bucket.Sum(record => record.Length);

التحديث

هذا كيف يمكنك الحصول على wheighted_average معين foreign_key.

IEnumerable<Record> records =
    (from record in Table2
    where record.ForeignKey == foreign_key
    where record.PCR != -1
    select record).ToList();
int wheighted_average = records.Sum(record => record.PCR * record.Length) /
    records.Sum(record => record.Length);

على ToList طريقة تسمى عند جلب السجلات هو تجنب تنفيذ الاستعلام مرتين في حين تجميع السجلات في منفصلين مجموع العمليات.

(الرد على jsmith تعليق على الجواب أعلاه)

إذا كنت لا ترغب في دورة من خلال بعض جمع يمكنك محاولة ما يلي:

var filteredList = Table2.Where(x => x.PCR != -1)
 .Join(Table1, x => x.ForeignKey, y => y.Key, (x, y) => new { x.PCR, x.Length });

int weightedAvg = filteredList.Sum(x => x.PCR * x.Length) 
    / filteredList.Sum(x => x.Length);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top