javascript - 如何按顺序和限制计算多个数组的数组元素计数之和?

标签 javascript arrays node.js dictionary set

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

每个id的count属性限制值为10(计数包含不同类型。例如:如果unique1在A类型中有10个计数,则对unique1处理类型B时,将不处理)。

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 }

我使用了一个集合来保存 id,它已经具有最大计数和映射来保存输出。

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 出现了两次,因此您的答案似乎不适用于这种情况。

最佳答案

您可以对每个 count 求和,而不是使用 maxed idSet 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; }

关于javascript - 如何按顺序和限制计算多个数组的数组元素计数之和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57035297/

相关文章:

javascript - 返回第一个找到的值对象

java - Java输出值随时间的变化

python - 如何获得 numpy 数组中非零值的位置?

python - 尝试从python-shell获取数据,将其解析为nodeJS中的对象

javascript - 事件.js : 141 throw er;//Unhandled 'error' event

javascript - 将 PV(蛋白质查看器)与 Vue.js 集成

JavaScript 对象继承问题

javascript - 将项目从 JSON 对象推送到 Angular js 中的下拉列表

arrays - 在 ruby​​ 中巧妙地将散列数组转换为 CSV

javascript - 将多数组转换为具有属性的对象数组