【问题标题】:How to calculate sum of count of array elements of multiple arrays by order and limit?如何按顺序和限制计算多个数组的数组元素计数之和?
【发布时间】:2019-07-15 07:43:49
【问题描述】:

我有 3 种不同类型的 3 个数组。每个数组都包含一个 id 的计数(可能像 arrayOfB 一样重复)。

每个id的count属性有一个限制值为10(count包括不同的类型。例如:如果unique1在type A中有10个count,当处理type B为unique1时,不会被处理)。

const arrayOfA = [
    {
        "type": "A", "count": 10, "id": "UID1"
    },
    {
        "type": "A", "count": 20, "id": "UID2"
    },
    {
        "type": "A", "count": 1, "id": "UID4"
    },
];

const arrayOfB = [
    {
        "type": "B", "count": 5, "id": "UID1"
    },
    {
        "type": "B", "count": 5, "id": "UID3"
    },
];

const arrayOfC = [
    {
        "type": "C", "count": 6, "id": "UID1"
    },
    {
        "type": "C", "count": 6, "id": "UID4"
    },
    {
        "type": "C", "count": 3, "id": "UID2"
    },
    {
        "type": "C", "count": 3, "id": "UID3"
    },
]

输出如下:

Map {
  'UID1|A' => 10,
  'UID2|A' => 10,
  'UID4|A' => 1,
  'UID3|B' => 5,
  'UID4|C' => 6 }

我使用了一个set来保存id,它已经有最大的count和map来保存输出了。

const maxed = new Set();
const elements = new Map();

arrayOfA.forEach(element => {
    if (element.count > 10) {
        maxed.add(`${element.id}`);
        elements.set(`${element.id}|${element.type}`, 10);
        console.log(elements)
        return;
    }

    if (elements.has(`${element.id}|${element.type}`)) {
        const newCount = elements.get(`${element.id}|${element.type}`) + element.count;
        newCount > 10 ? elements.set(`${element.id}|${element.type}`, 10) : elements.set(`${element.id}|${element.type}`, newCount);
        console.log(elements)
        return;
    }

    elements.set(`${element.id}|${element.type}`, element.count);
});

arrayOfB.forEach(element => {
    if (maxed.has(`${element.id}`)) {
        console.log(elements)
        return;
    }

    const countOfA = elements.has(`${element.id}|A`) ? elements.get(`${element.id}|A`) : 0;
    let newCount = countOfA + element.count;

    if (elements.has(`${element.id}|${element.type}`)) {
        newCount = newCount + element.get(`${element.id}|${element.type}`);
    }

    if (newCount > 10) {
        maxed.add(`${element.id}`);
        if ((10 - countOfA) > 0) elements.set(`${element.id}|${element.type}`, 10 - countOfA);
        console.log(elements)
        return;
    }

    elements.set(`${element.id}|${element.type}`, element.count);
})

arrayOfC.forEach(element => {
    if (maxed.has(`${element.id}`)) {
        console.log(elements)
        return;
    }

    const countOfA = elements.has(`${element.id}|A`) ? elements.get(`${element.id}|A`) : 0
    const countOfB = elements.has(`${element.id}|C`) ? elements.get(`${element.id}|C`) : 0

    let newCount = countOfA + countOfB + element.count;

    if (elements.has(`${element.id}|${element.type}`)) {
        newCount = newCount + element.get(`${element.id}|${element.type}`);
    }

    if (newCount > 10) {
        maxed.add(`${element.id}`);
        if ((10 - countOfA - countOfB) > 0); elements.set(`${element.id}|${element.type}`, 10 - countOfA - countOfB);
        console.log(elements)
        return;
    }

    elements.set(`${element.id}|${element.type}`, element.count);
})

如果有的话,我想问一下另一个更快的实现。我估计我的大 O 将是 O(n)(n 是 3 个数组的总长度)。如果数组的元素不包含相同的id。

编辑: 非常感谢你们,但似乎有一个极端情况。答案无法处理

var arrayOfA = [
    {
        "type": "A", "count": 10, "id": "UID1"
    },
    {
        "type": "A", "count": 20, "id": "UID2"
    },
    {
        "type": "A", "count": 1, "id": "UID4"
    },
];

const arrayOfB = [
    {
        "type": "B", "count": 5, "id": "UID1"
    },
    {
        "type": "B", "count": 5, "id": "UID3"
    },
    {
        "type": "B", "count": 1, "id": "UID3"
    },
];

var arrayOfC = [
    {
        "type": "C", "count": 6, "id": "UID1"
    },
    {
        "type": "C", "count": 6, "id": "UID4"
    },
    {
        "type": "C", "count": 3, "id": "UID2"
    },
    {
        "type": "C", "count": 3, "id": "UID3"
    },
]

在 arrayOfB 中,我的 UID3 出现了两次,所以你的答案似乎不适用于这种情况。

【问题讨论】:

  • 您可以使用 Maps of Maps,而不是使用字符串操作。 (或者,更简单地说,只是对象的对象。)
  • 我不明白你的“限制”功能。请您再解释一遍好吗?
  • 所以,假设一个唯一 id UID1 已经有 10 个类型 A 的计数。当我们转到类型 B 的数组时,相同的唯一 id UID1 有 X 类型 B 的计数。这个计数数量将不包括在内,因为唯一 ID UID1 已达到限制。
  • @trmaphi 好的,谢谢,我想我现在明白了
  • 顺便说一句,你在这里有一个空的声明:if ((10 - ACount - certCount) > 0); elements

标签: javascript arrays node.js dictionary set


【解决方案1】:

您可以将每个idcount 相加,而不是将Set 用于maxed id,并将其用于所有以下数组。

const
    getKey = (...a) => a.join('|'),
    rawData = [{ type: "A", count: 10, id: "UID1" }, { type: "A", count: 20, id: "UID2" }, { type: "A", count: 1, id: "UID4" }],
    rawData3 = [{ type: "B", count: 5, id: "UID1" }, { type: "B", count: 5, id: "UID3" }],
    rawData2 = [{ type: "C", count: 6, id: "UID1" }, { type: "C", count: 6, id: "UID4" }, { type: "C", count: 3, id: "UID2" }, { type: "C", count: 3, id: "UID3" }],
    elements = new Map,
    sums = new Map;

[rawData, rawData3, rawData2].forEach(a => a.forEach(({ type, count, id }) => {
    var sum = sums.get(id) || 0,
        key = getKey(id, type);

    sums.set(id, sum + count);

    if (sum >= 10) return;
    if (sum + count > 10) {
        if (10 - sum > 0) elements.set(key, 10 - sum);
        return;
    }
    elements.set(key, count);
}));

[...elements].map(a => console.log(a.join(': ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我不确定这会产生预期的结果吗?
  • 我也不确定。但是操作的结果集中缺少B
【解决方案2】:

基于您没有在预期结果集中包含“B”的假设,两个嵌套循环可以提供您想要的操作和过滤。

function getIdSummary(arrays) {

    const maxValue = 10;

    //Array of objects which we later conver to a map
    //The aim is ease of indexing during the iterations
    var summary = []


    //A heler to find if a maxed uid is found in the summary
    function isMaxed(uid) {
        return summary.some(item => {
            return item.uid === uid && item.count >= maxValue;
        })
    }



    //Iterate all the arrays
    arrays.forEach(anInputArray => {

        //Iterate each array
        anInputArray.forEach(item => {
            if (!isMaxed(item.id)) {
                summary.push({uid: item.id, type: item.type, count: item.count > maxValue ? 10 : item.count})
            }

        })

    })

    return new Map(summary.map(obj => {
        return [obj.uid + '|' + obj.type, obj.count]
    }))


}



var arrayOfA = [
    {
        "type": "A", "count": 10, "id": "UID1"
    },
    {
        "type": "A", "count": 20, "id": "UID2"
    },
    {
        "type": "A", "count": 1, "id": "UID4"
    },
];

const arrayOfB = [
    {
        "type": "B", "count": 5, "id": "UID1"
    },
    {
        "type": "B", "count": 5, "id": "UID3"
    },
];

var arrayOfC = [
    {
        "type": "C", "count": 6, "id": "UID1"
    },
    {
        "type": "C", "count": 6, "id": "UID4"
    },
    {
        "type": "C", "count": 3, "id": "UID2"
    },
    {
        "type": "C", "count": 3, "id": "UID3"
    },
]


var m = getIdSummary([arrayOfA, arrayOfB, arrayOfC]);

console.log(Array.from(m));

【讨论】:

    猜你喜欢
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    相关资源
    最近更新 更多