让我先解释一下我正在努力解决的问题.

我有一个现有的标签列表(键值对),当UI对话框打开时,将首先加载这些标签.

标签的示例如下:


const existingTags = [{
                    "key": "t1",
                    "value": "v1"
                }, {
                    "key": "t2",
                    "value": "v2"
                }
            ];
const modifiedTags = [{"key": "t1", "value": "v1"}, {"key": "t2", "value": "v2"}, {"key": "t3", "value": "v3"},];

我试过的代码是:(它在某种程度上是有效的,但并不优雅).如果可能的话,寻找一些元素解决方案.

<!DOCTYPE html>
<html>
<body>

<h1>JavaScript Arrays</h1>
<h2>The concat() Method</h2>


<p id="demo">TagsToBeAdded</p>
<p id="demo1">TagsToBeRemoved</p>
<p id="demo2">FinalAddList</p>


<script>
const existingTags = [{
                    "key": "t1",
                    "value": "v1"
                }, {
                    "key": "t2",
                    "value": "v2"
                }
            ];
const modifiedTags = [{"key": "t1", "value": "v1"}, {"key": "t2", "value": "v2"}, {"key": "t3", "value": "v3"},];
const tagsToBeAdded = modifiedTags.filter(item1 => !existingTags.some(item2 => (item2.key === item1.key && item2.value === item1.value)));
let tagsToBeDeleted = existingTags.filter(item1 => modifiedTags.some(item2 => (item2.key === item1.key && item2.value !== item1.value)));
const tagsToBeRetained = existingTags.filter(item1 => !tagsToBeDeleted.some(item2 => (item2.key === item1.key && item2.value === item1.value)));
if (!tagsToBeAdded.length && !tagsToBeDeleted.length) {
                tagsToBeDeleted = existingTags.filter(item1 => !modifiedTags.some(item2 => (item2.key === item1.key)));
}

const finalTagsListToBeAdded= tagsToBeRetained.concat(tagsToBeAdded);

const children = JSON.stringify(tagsToBeAdded); 
const children1 = JSON.stringify(tagsToBeDeleted); 
const children2 = JSON.stringify(finalTagsListToBeAdded); 

document.getElementById("demo").innerHTML = children
document.getElementById("demo1").innerHTML = children1
document.getElementById("demo2").innerHTML = children2
</script>

</body>
</html>

一些示例:

// Input
const existingTags = [{
                    "key": "t1",
                    "value": "v1"
                }, {
                    "key": "t2",
                    "value": "v2"
                }
            ];
const modifiedTags = [{"key": "t1", "value": "v1"}, {"key": "t2", "value": "v21"}, {"key": "t3", "value": "v3"}];

// Expected output:
tagsToBeAdded: [{"key":"t2","value":"v21"},{"key":"t3","value":"v3"}]
tagsToBeDeleted: [{"key":"t2","value":"v2"}]
finalTagsList: [{"key":"t1","value":"v1"},{"key":"t2","value":"v21"},{"key":"t3","value":"v3"}]
// Input:
const existingTags = [{
                    "key": "t1",
                    "value": "v1"
                }, {
                    "key": "t2",
                    "value": "v2"
                }
            ];
const modifiedTags = [{"key": "t1", "value": "v1"}, {"key": "t2", "value": "v2"}, {"key": "t3", "value": "v3"}];

// Expected output:
tagsToBeAdded: [{"key":"t3","value":"v3"}]
tagsToBeDeleted: []
finalTagsList: [{"key":"t1","value":"v1"},{"key":"t2","value":"v2"},{"key":"t3","value":"v3"}]

// Input:
const existingTags = [{
                    "key": "t1",
                    "value": "v1"
                }, {
                    "key": "t2",
                    "value": "v2"
                }
            ];
const modifiedTags = [{"key": "t1", "value": "v1"}];  // t2:v2 is removing

// Expected output:
tagsToBeAdded: []
tagsToBeDeleted: [{"key":"t2","value":"v2"}]
finalTagsList: [{"key":"t1","value":"v1"}]
// Input:
const existingTags = [{
                    "key": "t1",
                    "value": "v1"
                }, {
                    "key": "t2",
                    "value": "v2"
                }
            ];
const modifiedTags = [];  // all tags are dropped

// Expected output:
tagsToBeAdded: []
tagsToBeDeleted: [{"key":"t1","value":"v1"},{"key":"t2","value":"v2"}]
finalTagsList: []

Lodash也可以.

推荐答案

创建原始数组的浅层副本.在复制的数组中搜索两者中的元素,并将它们移动到各自的数组中.

这将导致existingTags的副本减少到tagsToBeDeletedmodifiedTags的副本减少到tagsToBeAdded,并且移动的副本最终位于未更改的标记中.

然后,将未更改的标记数组与tagsToBeAdded数组连接,形成finalTagsList.

请注意,modifiedTagsfinalTagsList实际上是相同的.因此,可以对以下内容进行优化,只需从数组副本中删除重复的元素.

const mangle = (existingTags, modifiedTags) => {
  const unchangedTags = [];
  existingTags = Array.from(existingTags);
  modifiedTags = Array.from(modifiedTags);
  for(let i = 0; i < existingTags.length; i++) {
    const a = existingTags[i];
    for(let j = 0; j < modifiedTags.length; j++) {
      const b = modifiedTags[j];
      if (a.key == b.key && a.value == b.value) {
        unchangedTags.push(a);
        existingTags.splice(i, 1);
        modifiedTags.splice(j, 1);
        i--;
        break;
      }
    }
  }
  return {
    tagsToBeAdded: modifiedTags,
    tagsToBeDeleted: existingTags,
    finalTagsList: unchangedTags.concat(modifiedTags);
  };
};

Javascript相关问答推荐

zoom svg以适应圆

每次子路由重定向都会调用父加载器函数

在React中获取数据后,如何避免不必要的组件闪现1秒?

jQuery提交按钮重新加载页面,即使在WordPress中使用preventDefault()

在观察框架中搜索CSV数据

如何在Vue 3中创建自定义 Select 组件,并将选项作为HTML而不是props 传递?

在open shadow—root中匹配时,使用jQuery删除一个封闭的div类

Next.js服务器端组件请求,如何发送我的cookie token?

在浏览器中触发插入事件时检索编码值的能力

如何在 Select 文本时停止Click事件?

令牌JWT未过期

如何使本地html页面在重新加载时保持当前可隐藏部分的打开状态?

如何使用画布在另一个内部绘制一个较小但相同的形状,同时保持恒定的边界厚度?

输入的值的类型脚本array.排序()

如何正确地在ComponentWillUnmount中卸载状态以避免内存泄漏?

需要刷新以查看Mern堆栈应用程序中的更改

如何从Reaction-Redux中来自API调用的数据中筛选值

浮动标签效果移除时,所需的也被移除

在特定区域的图像上 Select x和y,并在其上创建边框

Qualtrics联合实验脚本随机化条件