微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JS:比较对象数组中的值并检测匹配的值

如何解决JS:比较对象数组中的值并检测匹配的值

我在Javascript中有一系列对象,例如:

    var arrobj = [
  {'id': 1,'editors': 'Andrew||Maria','authors': 'Dorian||Gabi','agents': 'Bob||Peter'},{'id': 2,'editors': 'Dorian||Guybrush','author': 'Peter||Frodo','agents': 'Dorian||otto'},{'id': 3,'editors': 'Klaus||Otmar','authors': 'Jordan||Morgan','agents': 'Jordan||Peter'},];

我需要列出在每个对象中都有其角色的所有人员(编辑,作者和代理商)的列表。输出应包含一个新的键/值对(“涉及”),如下所示:

'involved': 'Andrew (editor)|| Maria (editor)|| Dorian (author) || Gabi (author) || Bob (agent) || Peter (agent)'

对象数组应类似于:

   var arrobj = [
  {'id': 1,'agents': 'Bob||Peter','involved': 'Andrew (editor)|| Maria (editor)|| Dorian (author) || Gabi (author) || Bob (agent) || Peter (agent)'},'authors': 'Peter||Frodo','agents': 'Dorian||otto','involved': 'Dorian (editor,agent) || Gybrush (editor) || Peter (author) || Frodo (author) || otto (author)'},'agents': 'Jordan||Peter','involved': 'Klaus (editor) || Otmar (editor) || Jordan (author,agent) || Morgan (author) || Peter (agent)'},];

如果一个人与多个角色相关联(例如,id 2-> Dorian出现在编辑和代理中),则他们在“参与”中的出现应该仅一次,但在方括号中都扮演两个角色(例如 Dorian(编辑,代理)

我对编程非常陌生,无法想出一种适当的方法。 第一步,我想我必须将所有值除以“ ||”分成数组,然后将每个名称与数组中的每个其他名称进行比较。

真的很感谢您为我的问题提供帮助。

解决方法

您需要收集所有名称及其工作类型并返回分组结果。

 const
     getInvolved = o => {
         const
             jobs = ['editor','author','agent'],names = jobs.reduce((r,k) => {
                 (o[k + 's'] || '').split('||').forEach(v => (r[v] ??= []).push(k));
                 return r;
             },{});

         return Object.entries(names).map(([k,v]) => `${k} (${v.join(',')})`).join(' || ')
     },array = [{ id: 1,editors: 'Andrew||Maria',authors: 'Dorian||Gabi',agents: 'Bob||Peter' },{ id: 2,editors: 'Dorian||Guybrush',author: 'Peter||Frodo',agents: 'Dorian||Otto' },{ id: 3,editors: 'Klaus||Otmar',authors: 'Jordan||Morgan',agents: 'Jordan||Peter' }],result = array.map(o => ({ ...o,involved: getInvolved(o) }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

,
  • map数组和destructure个对象获得一个roles个对象而没有id

  • 创建一个map对象,该对象会将每个人映射到他们的角色数组

  • 遍历roles对象中的每个键和split处的||以获取名称数组

  • 浏览名称并更新map对象。如果尚未添加name,请使用||=分配添加它

  • 使用slice删除角色的最后一个字符,以将其从复数形式转换为单数形式(从“代理”转换为“代理”)

  • map对象现在将每个人作为键,并将一组角色作为值。

    {
      Dorian: ["editor","agent"],Guybrush: ["editor"],Peter: ["author"],Frodo: ["author"],Otto: ["agent"]
    }
    
  • 遍历对象的条目并创建involved字符串

  • 使用附加的involved键返回新对象

const arrobj = [
  {'id': 1,'editors': 'Andrew||Maria','authors': 'Dorian||Gabi','agents': 'Bob||Peter'},{'id': 2,'editors': 'Dorian||Guybrush','authors': 'Peter||Frodo','agents': 'Dorian||Otto'},{'id': 3,'editors': 'Klaus||Otmar','authors': 'Jordan||Morgan','agents': 'Jordan||Peter'},];
    
const output = arrobj.map(({ id,...roles }) => {
  const map = {}
  
  for (const r in roles) {
    const names = roles[r].split("||")
    for (const name of names) {
      map[name] ||= []
      map[name].push(r.slice(0,-1))
    }
  }
  
  const involved = Object.entries(map)
                         .map(([name,values]) => `${name} (${values.join(",")})`)
                         .join(" || ")
                         
   return { id,...roles,involved }
})

console.log(output)

,

这是解决方案(ES5)的示例,可以进行一些优化。基本思想是推送所有编辑器,以供作者和代理检查先前组成的数组中是否已经存在。

var arrobj = [
  {'id': 1,];
    
function getInvolved(arr) {
  return arr.map(function(el) {
    var editors = el.editors.split('||');
    var authors = el.authors.split('||');
    var agents = el.agents.split('||'); 
    var involved = editors.map(function(editor) {
      return editor += ' (editor)';
    });
    
    authors.forEach(function(author) { 
      if(editors.indexOf(author) === -1) {
        involved.push(author + ' (author)');
      } else {
        involved = involved.map(function(inv) {
          if(inv.indexOf(author) > -1) {
            inv += '(author)';
          }
          return inv;
        });
      }
    });
    
    agents.forEach(function(agent) { 
      if(editors.indexOf(agent) === -1 && authors.indexOf(agent) === -1) {
        involved.push(agent + ' (agent)');
      } else {
        involved = involved.map(function(inv) {
          if(inv.indexOf(agent) > -1) {
            inv += '(agent)';
          }
          return inv;
        });
      }
    });
    el.involved = involved.join('||'); 
    return el;
  });
}

console.log(getInvolved(arrobj));

,

const arrobj = [
  {'id': 1,];

for (let obj of arrobj) {
  obj.involved = "";
  for (let key of Object.keys(obj)) {
    let strKey = [...key];
    strKey.pop();
    let role = strKey.join("");
    if (key === "involved") break;
    if (key !== "id") {
      obj.involved += obj[key]
        .split("||")
        .map((name) => name + "(" + role + ")||")
        .join("");
    }
    obj.involved = obj.involved.substr(0,obj.involved.length - 2).trim();
  }
}

console.log(arrobj);

这是运行中的副本:https://repl.it/join/juljqzxt-theketan2

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。