【问题标题】:Compare two array of objects and return matching values in a new array比较两个对象数组并在新数组中返回匹配值
【发布时间】:2022-01-02 19:23:22
【问题描述】:

我有两个对象数组:inputDatajobList。我必须比较两个对象数组的 primarySkills 数组,并仅返回两个数组中匹配的值。我的对象数组如下:

let inputData = [
    {
        "candidateID": "911772331",
        "skillSet": ["Information Technology"],
        "addressCity": "Bengaluru",
        "addressState": "KA",
        "country": "India",
        "primarySkills": ['asp.net', 'react', 'javascript'],
        "secondarySkills": ['powerbi', 'redux'],
        "preferredPositionType": [],
    }
]

let jobList = [
  {
    jobId: '600039355',
    jobType: 'fulltime',
    primarySkills: [ 'asp.net','node' ],
    secondarySkills: [ 'javascript' ],
    skillSet: [ 'javascript' ],
    Address: 'Indonesia, Bekasi Kabupaten, 53, Jalan Londan 5',
    City: 'Bekasi Kabupaten',
    State: 'JABODETABEK',
    Zipcode: '17522',
    Country: 'Indonesia'
  },
  {
    jobId: '562190375',
    jobType: 'fulltime',
    primarySkills: [ 'javascript','mainframe' ],
    secondarySkills: [ 'javascript' ],
    skillSet: [ 'javascript' ],
    Address: 'India, Pune, 411001, Pune, Pune Station',
    City: 'Pune',
    State: 'MH',
    Zipcode: '411001',
    Country: 'India'
  },
  {
    jobId: '883826845',
    jobType: 'fulltime',
    primarySkills: [ 'sqlserver', 'react', 'powershell' ],
    secondarySkills: [ 'powerbi' ],
    skillSet: [ 'powerbi' ],
    Address: 'ประเทศไทย, หมู่ที่ 3, 1234',
    City: 'หมู่ที่ 3',
    State: null,
    Zipcode: '57110',
    Country: 'ประเทศไทย'
  }
]

我已经完成了下面提到的代码来实现这一点:

jobList.forEach((item) => {
  inputData.forEach((data) => {
    for (let i = 0; i <= item.primarySkills.length; i++) {
      for (let j = 0; j <= data.primarySkills.length; j++) {
        if (item.primarySkills[i] === data.primarySkills[j]) {
          PMSkill.push(item.primarySkills[i]);
        } else {                                    
          PMSkill.push(0)
        }
      }
    }
  })
})
Expected output to be like in the PMSkill array:
let PMSkill= [
  {
    jobId: '600039355',
    jobType: 'fulltime',
    primarySkills: [ 'asp.net'],----here asp.net is the only skill matching with inputData primarySkill
    secondarySkills: [ 'javascript' ],
    skillSet: [ 'javascript' ],
    Address: 'Indonesia, Bekasi Kabupaten, 53, Jalan Londan 5',
    City: 'Bekasi Kabupaten',
    State: 'JABODETABEK',
    Zipcode: '17522',
    Country: 'Indonesia'
  },
  {
    jobId: '562190375',
    jobType: 'fulltime',
    primarySkills: [ 'javascript'],
    secondarySkills: [ 'javascript' ],
    skillSet: [ 'javascript' ],
    Address: 'India, Pune, 411001, Pune, Pune Station',
    City: 'Pune',
    State: 'MH',
    Zipcode: '411001',
    Country: 'India'
  },
  {
    jobId: '883826845',
    jobType: 'fulltime',
    primarySkills: ['react'],
    secondarySkills: [ 'powerbi' ],
    skillSet: [ 'powerbi' ],
    Address: 'ประเทศไทย, หมู่ที่ 3, 1234',
    City: 'หมู่ที่ 3',
    State: null,
    Zipcode: '57110',
    Country: 'ประเทศไทย'
  }
]

【问题讨论】:

  • 问题是什么?你的代码不起作用吗?如果是这样 - 会发生什么以及应该发生什么?如果代码不起作用,那么您需要什么帮助?
  • 是的,代码不起作用。目前发生的情况是 PMSkill 数组给出了错误或空白值。预期的是两个对象数组的primarySkills 字段应该是comapred 并且应该返回PMSkill 数组中的共同值。
  • @tanu ... OP 通常还描述了预期的结果/输出。
  • 对不起,这是我第一次@这个平台,所以错过了。当 inputData 第一次与 JobList 进行比较时,预期的输出应该是 ['javascript']。打印两个对象数组中的共同值。

标签: javascript arrays foreach reduce intersection


【解决方案1】:

您好,有一个我经常使用的简单方法

function arr_intersection(a1: number[], a2: number[]) {
  return a1.filter((x) => a2.includes(x));
}

你也可以使用lodash中的交集方法

const _ = require("lodash");
  
// Original array
let array1 = [1, 2, 4, 3, 4, 4]
let array2 = [2, 4, 5, 6]
let array3 = [2, 3, 5, 6]
  
// Using _.intersection() method
let newArray = _.intersection(
        array1, array2, array3);
  
// Printing original Array
console.log("original Array1: ", array1)
console.log("original Array2: ", array2)
console.log("original Array3: ", array3)
  
// Printing the newArray
console.log("new Array: ", newArray)

这里你可以发送多个数组,不像我的方法

【讨论】:

    【解决方案2】:

    function getIntersection(x, y) {
      // ensure two arrays ...
      const [
        comparisonBase, // ... the shorter one as comparison base
        comparisonList, // ... the longer one to filter from.
      ] = [[...x], [...y]]
        .sort((a, b) => a.length - b.length);
    
      // create a `Map` based lookup table from the shorter array.
      const itemLookup = comparisonBase
        .reduce((map, item) => map.set(item, true), new Map)
    
      // the intersection is the result of following filter task.
      return comparisonList.filter(item => itemLookup.has(item));
    }
    
    const inputData = [{
      "candidateID": "911772331",
      "skillSet": ["Information Technology"],
      "addressCity": "Bengaluru",
      "addressState": "KA",
      "country": "India",
      "primarySkills": ['asp.net', 'react', 'javascript'],
      "secondarySkills": ['powerbi', 'redux'],
      "preferredPositionType": [],
    }];
    const jobList = [{
      jobId: '600039355',
      jobType: 'fulltime',
      primarySkills: [ 'javascript' ],
      secondarySkills: [ 'javascript' ],
      skillSet: [ 'javascript' ],
      Address: 'Indonesia, Bekasi Kabupaten, 53, Jalan Londan 5',
      City: 'Bekasi Kabupaten',
      State: 'JABODETABEK',
      Zipcode: '17522',
      Country: 'Indonesia'
    }, {
      jobId: '562190375',
      jobType: 'fulltime',
      primarySkills: [ 'javascript' ],
      secondarySkills: [ 'javascript' ],
      skillSet: [ 'javascript' ],
      Address: 'India, Pune, 411001, Pune, Pune Station',
      City: 'Pune',
      State: 'MH',
      Zipcode: '411001',
      Country: 'India'
    }, {
      jobId: '883826845',
      jobType: 'fulltime',
      primarySkills: [ 'sqlserver', 'azure', 'powershell' ],
      secondarySkills: [ 'powerbi' ],
      skillSet: [ 'powerbi' ],
      Address: 'ประเทศไทย, หมู่ที่ 3, 1234',
      City: 'หมู่ที่ 3',
      State: null,
      Zipcode: '57110',
      Country: 'ประเทศไทย'
    }];
    
    const candidateSkills = inputData[0].primarySkills;
    const openJobsSkills = [...new Set(
      jobList.reduce((arr, { primarySkills }) => arr.concat(primarySkills), [])
    )];
    
    const skillIntersection = getIntersection(openJobsSkills, candidateSkills);
    
    console.log({ candidateSkills, openJobsSkills, skillIntersection });
    .as-console-wrapper { min-height: 100%!important; top: 0; }

    编辑根据 OP 的更详细的进一步要求

    “我想将inputData.primarySkillsjobList中的每个对象列表一一进行比较,并针对jobListprimarySkills字段更新匹配技巧。” p>

    在这种情况下,需要一项任务,该任务将 jobListforEach 项目重新分配为 primarySkills 属性值,并与从 inputData 获取的基本 primarySkills 数组的属性特定交集。

    所提供的解决方案利用forEach 及其2nd thisArg argument 将功能与外部范围引用/依赖项分离。

    根据是否需要让 jobList 保持不变/未触及,on 可能需要额外的映射任务,该任务必须创建每个 jobList 项目的深层克隆。

    function getIntersection(x, y) {
      // ensure two arrays ...
      const [
        comparisonBase, // ... the shorter one as comparison base
        comparisonList, // ... the longer one to filter from.
      ] = [[...x], [...y]]
        .sort((a, b) => a.length - b.length);
    
      // create a `Map` based lookup table from the shorter array.
      const itemLookup = comparisonBase
        .reduce((map, item) => map.set(item, true), new Map)
    
      // the intersection is the result of following filter task.
      return comparisonList.filter(item => itemLookup.has(item));
    }
    
    const inputData = [{
      "candidateID": "911772331",
      "skillSet": ["Information Technology"],
      "addressCity": "Bengaluru",
      "addressState": "KA",
      "country": "India",
      "primarySkills": ['asp.net', 'react', 'javascript'],
      "secondarySkills": ['powerbi', 'redux'],
      "preferredPositionType": [],
    }];
    
    const jobList = [{
      jobId: '600039355',
      jobType: 'fulltime',
      primarySkills: [ 'asp.net','node' ],
      secondarySkills: [ 'javascript' ],
      skillSet: [ 'javascript' ],
      Address: 'Indonesia, Bekasi Kabupaten, 53, Jalan Londan 5',
      City: 'Bekasi Kabupaten',
      State: 'JABODETABEK',
      Zipcode: '17522',
      Country: 'Indonesia'
    }, {
      jobId: '562190375',
      jobType: 'fulltime',
      primarySkills: [ 'javascript','mainframe' ],
      secondarySkills: [ 'javascript' ],
      skillSet: [ 'javascript' ],
      Address: 'India, Pune, 411001, Pune, Pune Station',
      City: 'Pune',
      State: 'MH',
      Zipcode: '411001',
      Country: 'India'
    }, {
      jobId: '883826845',
      jobType: 'fulltime',
      primarySkills: [ 'sqlserver', 'react', 'powershell' ],
      secondarySkills: [ 'powerbi' ],
      skillSet: [ 'powerbi' ],
      Address: 'ประเทศไทย, หมู่ที่ 3, 1234',
      City: 'หมู่ที่ 3',
      State: null,
      Zipcode: '57110',
      Country: 'ประเทศไทย'
    }];
    
    function updatePrimarySkillsWithIntersectionOfBoundBaseSkills(jobItem) {
      const basePrimarySkills = this;
    
      jobItem.primarySkills =
        getIntersection(jobItem.primarySkills, basePrimarySkills);
    }
    
    // if needed ... create new array with real `jobItem` clones ...
    const pmSkillList = jobList.map(jobItem =>
      JSON.parse(JSON.stringify(jobItem))
    );
    // ... otherwise (`jobList.forEach`) ... just ...
    
    // .... reassign the item specific `primarySkills` property value.
    pmSkillList.forEach(
      // the callback
      updatePrimarySkillsWithIntersectionOfBoundBaseSkills,
      // the 2nd `thisArg` argument
      inputData[0].primarySkills,
    );
    
    // log any involved data.
    console.log({ inputData, jobList, pmSkillList });
    .as-console-wrapper { min-height: 100%!important; top: 0; }

    【讨论】:

    • 感谢@Peter Seliger 回答我的问题。您能否再帮我一个方案(我还在我的代码 sn-p 中更新了上面的预期输出)。我想将 inputdata[primarySkills] 与 jobList 中的每个对象列表一一进行比较,并根据 jobList 的 primarySkills 字段更新匹配技能。
    • 你能帮我@Peter Seliger 上面解释的场景吗
    • @tanu ... 完成。
    • 非常感谢@Peter Seliger。再次回答我的问题真的很有帮助,非常好心。再次感谢!!!
    【解决方案3】:

    像这样更改您的验证

    
    matchingPrimarySkills = []
    
    jobList.forEach((job) => {
      inputData.forEach((candidate) => {
        job.primarySkills.forEach( (jobPrimarySkill) => {
           candidate.primarySkills.forEach( (candidatePrimarySkill) => {
            if (jobPrimarySkill === candidatePrimarySkill &&  matchingPrimarySkills.indexOf(jobPrimarySkill) === -1) {
              matchingPrimarySkills.push(jobPrimarySkill)
            }
          })
        })
      })
    })
    
    // With your examples, it will og [ "javascript"] without duplicates
    console.log(matchingPrimarySkills)
    

    【讨论】:

      【解决方案4】:

      这是实现所需输出的一种方法。仅显示相关属性仅用于演示。您可以将候选人从inputData 传递给getJobs(input) 函数,以从输入中获取与primarySkills 匹配的职位列表:

      let inputData = [
        { candidateID: '111111', primarySkills: ['asp.net', 'react', 'javascript'] },
        { candidateID: '222222', primarySkills: ['python'] },
        { candidateID: '333333', primarySkills: ['powershell', 'node'] },
      ]
      
      let jobList = [
        { jobId: '77777', primarySkills: ['asp.net', 'node'] },
        { jobId: '88888', primarySkills: ['javascript', 'python'] },
        { jobId: '99999', primarySkills: ['sqlserver', 'azure', 'powershell'] },
      ]
      
      function getJobs(input) {
        // Get a copy of jopList
        const temp = jobList.map(obj => { return { ...obj } })
      
        return temp.filter(job => {
          // Filter the job's primarySkills to only show
          // skills matching the candidates's primarySkills.
          job.primarySkills = job.primarySkills.filter(jobSkill =>
            input.primarySkills.includes(jobSkill)
          )
          return job.primarySkills.length
        })
      }
      
      // Get jobs for all candidates in inputData
      for (let candidate of inputData) {
        console.log(`\nJobs for candidateID ${candidate.candidateID}:\n`, getJobs(candidate))
      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        • 2021-11-04
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        相关资源
        最近更新 更多