根据内部条件以编程方式修改地图

时间:2018-07-22 17:01:47

标签: javascript dictionary ecmascript-6

例如,我有一张这样的地图

const Map = new Map().set('123', [ [ 'foo', 'bar' ] ]).set('456', [ [ 'baz', 'qux' ], [ 'quux', 'corge' ] ]);
/* 
The structure of the Map looks like this:
    Map {
       '123' => [ [ 'foo', 'bar' ] ],
       '456' => [ [ 'baz', 'qux' ], [ 'quux', 'corge' ] ] 
   } 
*/

我该如何删除数组中数组中第一个嵌套元素==='quux'的数组,以便它返回该数组?

Map {
    '123' => [ [ 'foo', 'bar' ] ],
    '456' => [ [ 'baz', 'qux' ] ] 
}

我知道如何通过

删除
Map.set('456', (Map.get('456')).filter(array => array[0] !== 'quux'));

但这只是因为我知道哪个键('456')中包含带有'quux'的元素。我不确定如何以编程方式扫过地图,然后找到相应的键,然后删除该项目。 Map中的键和值将是动态的(但结构相同),而要搜索的元素将是静态的,即:“ quux”,我的意思是Map中的内容可能会有所不同,而我只是执行搜索并删除。

5 个答案:

答案 0 :(得分:2)

您可以遍历Map的值,对每个值v使用findIndex来查看它是否包含第一个元素为quux的数组,以及{ {3}},如果有的话,将其排列:

const map = new Map().set('123', [ [ 'foo', 'bar' ] ]).set('456', [ [ 'baz', 'qux' ], [ 'quux', 'corge' ] ]);

console.log("before", [...map]);

for (const v of map.values()) {
  const index = v.findIndex((a) => a[0] === "quux");
  
  if (index > -1) {
    v.splice(index, 1);
  }
}

console.log("after", [...map]);

这是非破坏性替代方案,它通过提取旧条目的条目并splice将值map插入我们不需要的数组中来创建新的Map:

const before = new Map().set('123', [ [ 'foo', 'bar' ] ]).set('456', [ [ 'baz', 'qux' ], [ 'quux', 'corge' ] ]);

console.log("before", [...before]);

const after = new Map([...before].map(([k, v]) => {
  return [k, v.filter((a) => a[0] !== "quux")];
}))

console.log("after", [...after]);

注意:两种方法之间的区别是,第二种方法将删除以quux作为其第一个元素的 all 个数组,而第二种方法将仅删除第一个此类数组。当然,它们都可以更改以适合您需要的两个选项中的任何一个。

答案 1 :(得分:2)

您可以迭代地图,如果找到所需的值,请过滤数组并分配过滤后的数组。

const map = new Map([['123', [['foo', 'bar']]], ['456', [['baz', 'qux'], ['quux', 'corge']]]]);

map.forEach((v, k, m) => {
    if (v.some(a => a[0] === 'quux')) {
        m.set(k, v.filter(a => a[0] !== 'quux'));
    }
});

console.log([...map]);

答案 2 :(得分:1)

您可以使用如下所示的for循环动态地执行键操作:

顺便说一句,由于地图无法在代码段中正确显示,因此请打开您的devtools以签出新地图。

const Map = new Map().set('123', [
  ['foo', 'bar']
]).set('456', [
  ['baz', 'qux'],
  ['quux', 'corge']
]);


for (let el of Map) {
  Map.set(el[0], (Map.get(el[0])).filter(array => array[0] !== 'quux'));
}


console.log(Map);

我希望这是您想要的,否则您可以发表评论,我将对其进行查看;)。

答案 3 :(得分:1)

遍历映射的键值对,该值将具有外部数组,我们可以从中过滤出具有我们要查找的值的内部数组。我们可以从forEach函数中获取内部数组的索引,使用它可以使用splice函数从外部数组中删除内部数组。

const map = new Map().set('123', [ [ 'foo', 'bar' ] ]).set('456', [ [ 'baz', 'qux' ], [ 'quux', 'corge' ] ]);
map.forEach((v, k)=>
{
     v.forEach((arr, idx)=> {
     if(arr.includes('quux')){
            v.splice(idx,1);
        }
    },)
});
console.log(map);

答案 4 :(得分:0)

在过滤数组之前,不确定从性能角度考虑始终使用Array.prototype.filter还是使用Array.prototype.some更好。

此解决方案仅过滤所有数组,而无需先检查'quux'的出现。

const map = new Map().set('123', [ ['foo', 'bar' ] ]).set('456', [ [ 'baz', 'qux' ], [ 'quux', 'corge' ] ]);

map.forEach((val, key) => {
  val = val.filter(arr => arr[0] !== 'quux');
  map.set(key, val);
});

console.log(map);