找出对象的JavaScript数组中的差异和交点

发布于 2025-02-09 04:45:42 字数 4336 浏览 2 评论 0原文

让我首先解释我要解决的问题。

我有一个现有的标签列表(键值对),当UI对话框打开时,它将首先加载。 然后,用户可以添加更多标签,可以删除标签或可以编辑标签。 不幸的是,我将通过修改的标签列表的API不支持编辑。因此,编辑是指:删除修改后的条目并添加新条目。

标签的一个示例是:


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也可以。

Let me first explain the issue I am trying to solve.

I have an existing list of Tags(key-value pair), which will be loaded first when a UI dialog will open up.
Then user can add more tags, can remove tags or can edit the tags.
The API where I will pass the modified tag list, unfortunately, does not support edit. So edit means: delete the modified entry and add the new entry.

An example of the tags are:


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

The code I have tried out is this: (It somehow works, but not elegant). Looking for some element solution, if possible.

<!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>

Some of the examples:

// 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 is also ok.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红颜悴 2025-02-16 04:45:42

创建原始阵列的浅副本。搜索复制的阵列中,以获取两者中的元素,并将它们移至自己的阵列。

这会导致easuntags的副本简化为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);
  };
};

Create shallow copies of the original arrays. Search through the copied arrays for elements that are in both and move them to their own array.

This causes the copy of existingTags to be reduced to tagsToBeDeleted, the copy of modifiedTags to be reduced to tagsToBeAdded, and the moved duplicates end up in the unchanged tags.

The unchanged tag array is then concatenated with the tagsToBeAdded array to make finalTagsList.

Note that modifiedTags and finalTagsList are effectively the same thing. Because of this, the below could be optimized to just drop the duplicate elements from the array copies.

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);
  };
};
酒浓于脸红 2025-02-16 04:45:42

直截了当的(不一定是最有效的,但对于一组可以手动管理的标签,我认为这不会有所作为)是以下方法。这假定标签的是唯一的,并且keyvalue是原始类型,可以与= =进行比较。 ==。请参阅代码中的注释以获取说明。

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

//tags that exist in existingTags but not in modifiedTags have to be deleted, 
const delTags1 = existingTags.filter(x => 
  !modifiedTags.find(y => x.key === y.key));

//tags that exist in both but differ in value have to be deleted
const delTags2 = existingTags.filter(x =>
  !!modifiedTags.find(y => x.key === y.key && x.value !== y.value));

//tags that exist in modifiedTags but not in existingTags have to be added
const addTags1 = modifiedTags.filter(y => 
  !existingTags.find(x => x.key === y.key));

//tags that exist in both but have a different value have to be readded
const addTags2 = modifiedTags.filter(y => 
  existingTags.find(x => x.key === y.key && x.value !== y.value));

//tags that exist in both and have the same value have to be retained
const keepTags = existingTags.filter(x => 
  modifiedTags.find(y => x.key === y.key && x.value === y.value));


const finalDelete = [...delTags1, ...delTags2];
const finalAdd = [...addTags1, ...addTags2, ...keepTags];

console.log(JSON.stringify(finalDelete));
console.log(JSON.stringify(finalAdd));

A straight forward (not necessarily the most efficient, but for a set of tags that's manually managable, I don't think it makes difference) approach would be the following. This assumes, that the key of a tag is unique and both, key and value are primitive types that can be compared with ===. See the comments in code for explanation.

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

//tags that exist in existingTags but not in modifiedTags have to be deleted, 
const delTags1 = existingTags.filter(x => 
  !modifiedTags.find(y => x.key === y.key));

//tags that exist in both but differ in value have to be deleted
const delTags2 = existingTags.filter(x =>
  !!modifiedTags.find(y => x.key === y.key && x.value !== y.value));

//tags that exist in modifiedTags but not in existingTags have to be added
const addTags1 = modifiedTags.filter(y => 
  !existingTags.find(x => x.key === y.key));

//tags that exist in both but have a different value have to be readded
const addTags2 = modifiedTags.filter(y => 
  existingTags.find(x => x.key === y.key && x.value !== y.value));

//tags that exist in both and have the same value have to be retained
const keepTags = existingTags.filter(x => 
  modifiedTags.find(y => x.key === y.key && x.value === y.value));


const finalDelete = [...delTags1, ...delTags2];
const finalAdd = [...addTags1, ...addTags2, ...keepTags];

console.log(JSON.stringify(finalDelete));
console.log(JSON.stringify(finalAdd));

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文