[英]JavaScript: Find Matches AND Differences in two Arrays of Objects
好的,所以這是一個艱難的過程。 我認為。
我有兩個 arrays 對象,其中包含一些有關 pod 的信息。 我希望提供環境的並排比較,以顯示 pod 包含完全相同的圖像的位置; 訣竅是我還需要捕捉圖像不匹配的豆莢。 結果將呈現在一個看起來像這樣的表上(至少作為第一次迭代):
|---------------------|------------------|------------------|
| Pod Name | Image from Env1 | Image from Env2 |
|---------------------|------------------|------------------|
| foo | foo:1.0.0 | foo:1.0.0 | <---- images match
|---------------------|------------------|------------------|
| foo | foobar:1.0.0 | | <---- No match for image tag; image name different from the pod name as the pods may contain multiple images
|---------------------|------------------|------------------|
| foo | | foobar:2.0.0 | <---- As above
|---------------------|------------------|------------------|
| bar | bar:2.0.0 | bar:2.0.0 | <---- images match
|---------------------|------------------|------------------|
| baz | baz:1.0.0 | | <----
|---------------------|------------------|------------------| Note the 'no match'; so own row for now
| baz | | baz:2.0.0 | <----
|---------------------|------------------|------------------|
稍后我將使用 CSS 來突出匹配與差異。
我最苦惱的事情是:
foo
pod)[{ "Pod Name": "foo", "Image_Env_1": foo:1.0.0", "Image_Env_2": foo:1.0.0"}...
並留下空白字符串(如表)用於不匹配情況下的值。 但這可能會與foo
pod 中具有不同圖像標簽的其他圖像發生沖突。 所以Env1
數組看起來像這個片段:
[ { "Image": { "S": "foo:1.0.0" }, "Pod Name": { "S": "foo" } }, { "Image": { "S": "foobar:0.2.0" }, "Pod Name": { "S": "foo" } }, { "Image": { "S": "bar:1.0.0" }, "Pod Name": { "S": "bar" } }, { "Image": { "S": "baz:1.0.0" }, "Pod Name": { "S": "baz" } }, { "Image": { "S": "qux:1.0.0" }, "Pod Name": { "S": "foo" } } ]
Env2
數組:
[ { "Image": { "S": "foo:2.0.0" }, "Pod Name": { "S": "foo" } }, { "Image": { "S": "foobar:0.2.0" }, "Pod Name": { "S": "foo" } }, { "Image": { "S": "bar:1.0.0" }, "Pod Name": { "S": "bar" } }, { "Image": { "S": "baz:3.0.0" }, "Pod Name": { "S": "baz" } } ]
您可以編寫一個小助手方法來聚合來自您的 env 文件的信息,即首先按 pod 分組,然后聚合使用的圖像。 過濾在多個環境中使用圖像的條目應該是微不足道的。
類似的東西(請注意,這適用於任意數量的環境):
function getAggregatedPodInfos(...environments) {
const aggregatedInfos = {pods: {}, environments: []};
environments.forEach(env => addEnvironmentInfos(env, aggregatedInfos))
return aggregatedInfos;
}
function addImageInfoByEnvironment(pod, environment, imageName) {
if (!pod.imageInfo[environment.envName]) {
pod.imageInfo[environment.envName] = [];
}
pod.imageInfo[environment.envName].push(imageName)
}
function addEnvironmentInfos(environment, envInfo) {
envInfo.environments.push(environment.envName);
for (const envEntry of environment.data) {
const podName = envEntry["Pod Name"]["S"];
const imageName = envEntry["Image"]["S"];
if (!envInfo.pods[podName]) {
envInfo.pods[podName] = {imageInfo: {}};
}
addImageInfoByEnvironment(envInfo.pods[podName], environment, imageName);
}
}
const res = getAggregatedPodInfos({envName: 'env1', data: env1}, {envName: 'env2', data: env2});
console.log(JSON.stringify(res))
這將打印:
{
"pods": {
"foo": {
"imageInfo": {
"env1": ["foo:1.0.0", "foobar:0.2.0", "qux:1.0.0"],
"env2": ["foo:2.0.0", "foobar:0.2.0"]
}
},
"bar": {
"imageInfo": {
"env1": ["bar:1.0.0"],
"env2": ["bar:1.0.0"]
}
},
"baz": {
"imageInfo": {
"env1": ["baz:1.0.0"],
"env2": ["baz:3.0.0"]
}
}
},
"environments": ["env1", "env2"]
}
這非常艱難:但我認為這個過程可以分為兩個主要階段:
第一步可以進一步分解為操作原始數據,然后對其進行處理。
在處理 Pod Name 等類別時,我喜歡做的是創建包含 Set 對象的 Map 對象。 在這種情況下,它可能看起來像這樣:
// Let's assume Env1 is loaded already.
const podNameMap1 = new Map();
Env1.forEach( (value, index) => {
// Here 'value' is element in Env1
const podName = value['Pod Name'].S;
const podValue = podNameMap.get(podName);
// returns undefined if it does not exist
if (!podValue) {
podNameMap.set(podName, new Set(value['Image'].S) );
// If there is no podValue, set podName to a new Set with the images in it.
} else {
// Here there is a podValue, and we can add a new member to the Set.
podValue.add(value['Images'].S);
// podValue is a Set object which means the map value needs to be set one time.
}
});
在podNameMap1
的末尾包含所有 pod 及其所有圖像。 下一步是對Env2
做同樣的事情,此時有兩個不同 pod 名稱和圖像的映射。
之后就可以進行比較了,這比創建地圖要復雜:
// Let's assume podNameMap1 and podNameMap2 are both loaded.
// I don't know if it's possible for pods to be mismatched,
// I'm going to assume they are cannot be.
// Images in both
const inBothEnvsMap = new Map();
// Images in env1 but not env2
const inEnv1Map = new Map();
// Images in env2 but not env1
const inEnv2Map = new Map();
podNameMap1.forEach( (imageSet1, podName) => {
// Here, imageSet1 and podName are self explanitory
const imageSet2 = podNameMap1.get(podName); // assuming this is always the case
// Computing the set intersections n stuff
const inEnv1 = new Set();
const inEnv2 = new Set();
const inBothEnvs = new Set();
// Note: I wish JS had built in set operations because there's probably
// a better way to do this but alas...
imageSet1.forEach( image => {
if (imageSet2.has(image))
inBothEnvs.add(image);
else // in imageSet1 only
inEnv1.add(image);
});
// now inEnv1 AND inBothEnvs are complete
imageSet2.forEach( image => {
if (!imageSet1.has(image))
inEnv2.add(image);
});
// now this pod is done
inBothEnvsMap.set(podName, inBothEnvs);
inEnv1Map.set(podName, inEnv1);
inEnv2Map.set(podname, inEnv2);
});
此時,這就是“查找匹配和差異”步驟。
繼續下一步“將信息轉換成有用的東西”是不太特定於簡單集合操作的部分,所以我不能就此給出合理的建議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.