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

时间:2019-06-25 17:13:24

标签: javascript arrays dictionary

我有两个数组

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的id映射到array2的tags并显示array1的相应标题。

新的array2应该看起来像

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

我这样做是为了获得array1映射,然后卡住了。

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

7 个答案:

答案 0 :(得分:2)

您可以使用reduce创建一个映射对象,其中每个id作为键,title作为值。然后在maparray2上方分别tagssplit上获得新标签

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)

您还可以使用Object.fromEntries()

获取映射对象
const map = Object.fromEntries(array1.map(({ id, title }) => [id, title]));

然后使用正则表达式/\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)

答案 1 :(得分:1)

您可以使用filtermapjoin方法,首先在array1中拆分标签和过滤标签。

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);

答案 2 :(得分:1)

这是一个解决方案

我正在使用.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)

答案 3 :(得分:0)

您可以尝试关注

  • 使用Array.reducearray1转换为object作为{strong>键和id作为 value < / strong>(第1步
  • 使用Array.forEach遍历title以更新其标签属性
    • 要先array2 split更新tags属性,以将其转换为,
    • Maparray中的每个值与其在步骤1
    • 中创建的array中的对应值
    • JoinObject返回数组,并分配回,

tags

答案 4 :(得分:0)

要获得预期的结果,请使用以下循环array1的选项,并用title替换array2标签

  1. 使用forEach循环Array1
  2. 使用数组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);

答案 5 :(得分:0)

我会考虑将其分解为几个可重用的功能。当然,这可能是过早的抽象,但是我在这里经常看到这种问题的变体,以至于我对基本原理有所了解。

我们希望能够查找存储为数组的列表中的值,其中可能包含任意字段名称。因此,我们使用函数makeDictionary来获取字段名和数组,并返回一个映射它们的对象,例如{'1':'Writing','2':'Singing',...} `。

然后,我们可以使用fillField提供字典,字段名称和对象,然后用在字典中查找标签的结果替换该字段。这是针对该问题的一个更具体的说明,主要是因为标签的逗号分隔字符串格式比数组(如果是数组)要麻烦一些。

有了这些,useTags易于编写,并且是这里第一个直接针对您的需求的功能。它结合了上述内容,并为字典提供了字段名idtitle,并为您的主要对象提供了字段tags

这看起来像是组合:

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

请注意,我对tags: "2,3"tags: "Singing,Dance"格式有点自由,增加了一些空白。删除它是微不足道的。但是,如果可能的话,更好的办法是将其更改为使用数组作为标签。

答案 6 :(得分:0)

您可以使用真实的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; }