简体   繁体   English

将数组元素与其他数组映射

[英]Mapping the array element with other array

I have two arrays 我有两个数组

array1 = [{id:"1",title:"Writing"},{id:"2",title:"Singing"},{id:"3",title:"Dance"}];

array2 = [{tags: "1",title: "USA",type: "text"},
{tags: "1,2,3",title: "Japan",type: "image"},
{tags: "2,3",title: "Japan",type: "image"}];

I have to map the id of the array1 to tags of the array2 and display the corresponding title from the array1. 我必须将array1的id映射到array2的tags ,并显示array1的相应标题。

The new array2 should look like, 新的array2应该看起来像,

array2=[{tags:"Writing",title:"USA", type:"text"},
{tags: "Writing,Singing,Dance",title: "Japan",type: "image"},
{tags: "Singing,Dance",title: "Japan",type: "image"}];

I did this to get the array1 mapping and got stuck after that. 我这样做是为了获得array1映射,然后卡住了。

var newtags= (array1).map(obj=>{
var rObj={};
rObj[obj.id]=obj.title;
return rObj;
});

You can create a mapping object with each id as key and title as value using reduce . 您可以使用reduce创建一个映射对象,每个id为键, title为值。 Then map over array2 and split each tags to get the new tags 然后maparray2split每个tags以获取新标签

 const array1=[{id:"1",title:"Writing"},{id:"2",title:"Singing"},{id:"3",title:"Dance"}], array2=[{tags:"1",title:"USA",type:"text"},{tags:"1,2,3",title:"Japan",type:"image"},{tags:"2,3",title:"Japan",type:"image"}] const map = array1.reduce((r, { id, title }) => ({ ...r, [id]: title }), {}); const output = array2.map(({ tags, ...rest }) => { const newTags = tags.split(',').map(id => map[id]).join(',') return { tags: newTags, ...rest } }) console.log(output) 

You could also get the mapping object using Object.fromEntries() 您还可以使用Object.fromEntries()获取映射对象

const map = Object.fromEntries(array1.map(({ id, title }) => [id, title]));

Then use the regex /\\d+(?=,|$)/ to match the numbers and replace them with their respective title s 然后使用正则表达式/\\d+(?=,|$)/匹配数字并将其替换为各自的title s

 const array1=[{id:"1",title:"Writing"},{id:"2",title:"Singing"},{id:"3",title:"Dance"}], array2=[{tags:"1",title:"USA",type:"text"},{tags:"1,2,3",title:"Japan",type:"image"},{tags:"2,3",title:"Japan",type:"image"}] const map = Object.fromEntries(array1.map(({ id, title }) => [id, title])); const output = array2.map(({ tags, ...rest }) => { const newTags = tags.replace(/\\d+(?=,|$)/g, n => map[n]) return { tags: newTags, ...rest } }) console.log(output) 

You can use filter , map and join method, split tags and filter tags in array1 first. 您可以使用filtermapjoin方法,首先在array1中拆分标签和filter标签。

var newtags= (array2).map(obj=>{
   let tags = obj.tags.split(",");
   let titles = array1.filter(c=>tags.includes(c.id)).map(c=>c.title);
   obj.tags = titles.join();
   return obj;
});

 array1 = [{id:"1",title:"Writing"},{id:"2",title:"Singing"},{id:"3",title:"Dance"}]; array2 = [{tags: "1",title: "USA",type: "text"}, {tags: "1,2,3",title: "Japan",type: "image"}, {tags: "2,3",title: "Japan",type: "image"}]; var newtags= (array2).map(obj=>{ let tags = obj.tags.split(","); let titles = array1.filter(c=>tags.includes(c.id)).map(c=>c.title); obj.tags = titles.join(); return obj; }); console.log(newtags); 

Here's a solution 这是一个解决方案

I'm using .map, .reduce and .replace to join array1 and array2 together. 我正在使用.map,.reduce和.replace将array1和array2连接在一起。

 const array1 = [ { id: "1", title: "Writing" }, { id: "2", title: "Singing" }, { id: "3", title: "Dance" } ] const array2 = [ { tags: "1", title: "USA", type: "text" }, { tags: "1,2,3", title: "Japan", type: "image" }, { tags: "2,3", title: "Japan", type: "image" } ] const array3 = array2.map(item => ({ ...item, tags: array1.reduce((tags, {id, title}) => tags.replace(id, title), item.tags), })) console.log(array3) 

You can try following 您可以尝试关注

  • Use Array.reduce to convert array1 into an object with id as key and title as value ( Step 1 ) 使用Array.reducearray1转换为以idtitleobject步骤1
  • Iterate over array2 using Array.forEach to update its tags property 使用Array.forEach遍历array2以更新其标签属性
    • To update tags property first split it by , to convert into an array 要更新tags属性,请先拆分,以将其转换为array
    • Map each value in array to its corresponding value in Object created in step 1 array每个值映射到其在步骤1中创建的Object中的对应值
    • Join back the array with , and assign back to tags 使用联接阵列,并分配回tags

 let array1 = [{id:"1",title:"Writing"},{id:"2",title:"Singing"},{id:"3",title:"Dance"}]; let array2 = [{tags: "1",title: "USA",type: "text"},{tags: "1,2,3",title: "Japan",type: "image"},{tags: "2,3",title: "Japan",type: "image"}]; let obj = array1.reduce((a,c) => Object.assign(a, {[c.id] : c.title}), {}); array2.forEach(o => o.tags = o.tags.split(",").map(v => obj[v]).join(",")); console.log(array2); 

To achieve expected result, use below option of looping array1 and replacing array2 tags with title 为了达到预期的效果,请使用下面的循环array1选项,并用title替换array2标签。

  1. Loop Array1 using forEach 使用forEach循环Array1
  2. Replace array2 tags with each array1 title using array id 使用数组ID用每个array1标题替换array2标签

 array1 = [{id:"1",title:"Writing"},{id:"2",title:"Singing"},{id:"3",title:"Dance"}]; array2 = [{tags: "1",title: "USA",type: "text"}, {tags: "1,2,3",title: "Japan",type: "image"}, {tags: "2,3",title: "Japan",type: "image"}]; array1.forEach(v =>{ const re = new RegExp(v.id, "g"); array2 = JSON.parse(JSON.stringify(array2).replace(re, v.title)) }) console.log(array2); 

I would consider breaking this down into several reusable functions. 我会考虑将其分解为几个可重用的功能。 Of course it might be premature abstraction, but I've seen variants of this questions like often enough here that it makes sense to me to look toward the fundamentals. 当然,这可能是过早的抽象,但是我在这里经常看到这种问题的变体,这足以使我了解基本原理。

We want to be able to look up the values in a list stored as an array with what might be arbitrary field names. 我们希望能够查找存储为数组的列表中的值,其中可能包含任意字段名称。 So we use a function makeDictionary that takes both the field names and the array and returns an object that maps them, such as {'1': 'Writing', '2': 'Singing',...}`. 因此,我们使用函数makeDictionary来获取字段名称和数组,并返回一个映射它们的对象,例如{'1':'Writing','2':'Singing',...}`。

Then we can use fillField supplying a dictionary, a field name, and an object, and replace that field with the result of looking up the tags in the dictionary. 然后,我们可以使用fillField提供一个字典,一个字段名称和一个对象,并用在字典中查找标签的结果替换该字段。 This is a little more specific to the problem, mostly because the comma-separated string format for your tags is a little more cumbersome than it might be if it were an array. 这个问题更具体一些,主要是因为标签的逗号分隔字符串格式比如果是数组要麻烦一些。

With these, useTags is simple to write, and it is the first function here focused directly on your needs. 有了这些, useTags易于编写,并且是这里第一个直接针对您的需求的功能。 It combines the above, supplying the field names id and title for the dictionary and tags for your main objects. 它结合了上述内容,并提供了字典的字段名称idtitle以及主要对象的tags

This is what it looks like combined: 这是看起来很像的组合:

 const makeDictionary = (keyName, valName) => (arr) => arr .reduce ( (a, {[keyName]: k, [valName]: v}) => ({...a, [k]: v}) , {} ) const fillField = (field, dict) => ({[field]: f, ...rest}) => ({ ...rest, [field]: f .split (/,\\s*/) .map (t => dict[t]) .join (', ') }) const useTags = (tags, dict = makeDictionary ('id', 'title') (tags) ) => (objs) => objs .map ( fillField ('tags', dict) ) const tags = [{id: "1", title: "Writing"}, {id: "2", title: "Singing"}, {id: "3", title: "Dance"}]; const updateTags = useTags (tags) const items = [{tags: "1", title: "USA", type: "text"}, {tags: "1, 2, 3", title: "Japan", type: "image"}, {tags: "2, 3", title: "Japan", type: "image"}]; console .log ( updateTags (items) ) 

Note that I took a little liberty with the tags: "2,3" and tags: "Singing,Dance" formats, adding a little white space. 请注意 ,我对tags: "2,3"tags: "Singing,Dance"格式有一点自由,增加了一些空白。 It's trivial to take this out. 删除它是微不足道的。 But even better, if possible, would be to change this to use arrays for your tags. 但是,如果可能的话,更好的办法是将其更改为使用数组作为标签。

You could take a real Map and map the values to the new objects. 您可以使用真实的Map并将值映射到新对象。

 var array1 = [{ id: "1", title: "Writing" }, { id: "2", title: "Singing" }, { id: "3", title: "Dance" }], array2 = [{ tags: "1", title: "USA", type: "text" }, { tags: "1,2,3", title: "Japan", type: "image" }, { tags: "2,3", title: "Japan", type: "image" }], tags = array1.reduce((m, { id, title }) => m.set(id, title), new Map), result = array2.map(o => ({ ...o, tags: o.tags.split(',').map(Map.prototype.get, tags).join() })); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM