我该如何写这份报告候选人的功能更好?

问题描述 投票:0回答:4

这是名为candidatesArray的数组中的输入数据:

[ 
 {"name":"george","languages":["php","javascript","java"],"age":19,"graduate_date":1044064800000,"phone":"32-991-511"},
 {"name":"anna","languages":["java","javascript"],"age":23,"graduate_date":1391220000000,"phone":"32-991-512"},
 {"name":"hailee","languages":["regex","javascript","perl","go","java"],"age":31,"graduate_date":1296525600000,"phone":"32-991-513"}
]

由于该函数,我需要在此集合中进行转换:

{candidates: [
    {name: "George", age: 19, phone: "32-991-511"},
    {name: "Hailee", age: 31, phone: "32-991-513"},
    {name: "Anna", age: 23, phone: "32-991-512"}
],
languages: [
    {lang:"javascript",count:1}, 
    {lang:"java", count:2}, 
    {lang:"php", count:2}, 
    {lang:"regex", count:1}
]}

函数repCandidates:

const reportCandidates = (candidatesArray) => {
   return repObject}

  • 我需要用 javascript ES6 编写它
  • 我不应该使用循环(for、while、repeat),但 foreach 是允许的,如果我使用“reduce”函数可能会更好
  • 应聘者应按照毕业日期填写姓名、年龄和电话。
  • 返回的语言及其计数器应按字母顺序排列。

请访问 https://codepen.io/rillervincci/pen/NEyMoV?editors=0010 查看我的代码。

javascript arrays json sorting collections
4个回答
1
投票

一种选择是首先将

reduce
放入
candidates
子对象中,同时
push
将每个
langauges
放入数组中。

迭代后,对

candidates
进行排序并从每个候选者中删除
graduate_date
属性,然后再次使用
reduce
languages
数组转换为按语言索引的数组,每次递增
count
属性:

const input = [{
  "name": "george",
  "languages": ["php", "javascript", "java"],
  "age": 19,
  "graduate_date": 1044064800000,
  "phone": "32-991-511"
}, {
  "name": "anna",
  "languages": ["java", "javascript"],
  "age": 23,
  "graduate_date": 1391220000000,
  "phone": "32-991-512"
}, {
  "name": "hailee",
  "languages": ["regex", "javascript", "perl", "go", "java"],
  "age": 31,
  "graduate_date": 1296525600000,
  "phone": "32-991-513"
}];


const output = input.reduce((a, { languages, ...rest }) => {
  a.candidates.push(rest);
  a.languages.push(...languages);
  return a;
}, { candidates: [], languages: [] });

output.candidates.sort((a, b) => a.graduate_date - b.graduate_date);
output.candidates.forEach(candidate => delete candidate.graduate_date);

output.languages = Object.values(
  output.languages.reduce((a, lang) => {
    if (!a[lang]) a[lang] = { lang, count: 0 };
    a[lang].count++;
    return a;
  }, {})
);
output.languages.sort((a, b) => a.lang.localeCompare(b.lang));

console.log(output);


0
投票

通常的做法是在

reduce()
中完成所有操作,但有时如果将其分解一下会更容易阅读。这将创建一个
counter
对象作为跟踪语言计数的助手。
map()
在数组上提取语言和个人信息,然后将它们放在一起:

let arr = [ {"name":"george","languages":["php","javascript","java"],"age":19,"graduate_date":1044064800000,"phone":"32-991-511"},{"name":"anna","languages":["java","javascript"],"age":23,"graduate_date":1391220000000,"phone":"32-991-512"},{"name":"hailee","languages":["regex","javascript","perl","go","java"],"age":31,"graduate_date":1296525600000,"phone":"32-991-513"}]
 
let lang_counter = {
  // helper keeps counts of unique items
  counts:{},
  add(arr){
     arr.forEach(item => this.counts[item] = this.counts[item] ? this.counts[item] + 1 : 1)
  },
  toarray(){
    return Object.entries(this.counts).map(([key, val]) => ({[key]: val}))
  }
}

// iterate over object to create candidates 
let candidates = arr.map(row => {
  let {languages, ...person} = row
  lang_counter.add(languages)  // side effect
  return person
})

// put them together
console.log({candidates, languages:lang_counter.toarray()})


0
投票

您可以使用

Array.reduce
Object.values
,如下所示

let arr = [{"name":"george","languages":["php","javascript","java"],"age":19,"graduate_date":1044064800000,"phone":"32-991-511"},{"name":"anna","languages":["java","javascript"],"age":23,"graduate_date":1391220000000,"phone":"32-991-512"},{"name":"hailee","languages":["regex","javascript","perl","go","java"],"age":31,"graduate_date":1296525600000,"phone":"32-991-513"}]


let res = arr.reduce((o, {name, age, phone, graduate_date, languages}) => {
    o.candidates.push({name, age, phone, graduate_date})
  
    languages.forEach(l => {
      o.languages[l] = o.languages[l] || { lang:l, count: 0 }
      o.languages[l].count++
    })
  
    return o
  }
 , { candidates: [], languages: {}})

res.candidates = res.candidates.sort((a,b) => a.graduate_date - b.graduate_date)
                               .map(({ graduate_date, ...rest }) => rest)

res.languages = Object.values(res.languages).sort((a,b) => a.lang.localeCompare(b.lang))
  
console.log(res)


0
投票

如果您愿意使用不仅仅是普通 JavaScript,我可以提供直观的解决方案。

import assert from "assert";
import { ORDER } from "@ut8pia/classifier/global.js";
import { TrueSet } from "@ut8pia/classifier/queue/TrueSet.js";

const 
    data = [ 
        {"name":"George","languages": "php","javascript","java"],"age":19,"graduate_date":1044064800000,"phone":"32-991-511"},
        {"name":"Anna","languages":["java","javascript"],"age":23,"graduate_date":1391220000000,"phone":"32-991-512"},
        {"name":"Hailee","languages":["regex","javascript","perl","go","java"],"age":31,"graduate_date":1296525600000,"phone":"32-991-513"}
],

    expected = {
        candidates: [
            {name: "George", age: 19, phone: "32-991-511"},
            {name: "Hailee", age: 31, phone: "32-991-513"},
            {name: "Anna", age: 23, phone: "32-991-512"}
        ],

        languages: [
            {lang: "go", count: 1},
            {lang: "java", count: 3}, 
            {lang: "javascript", count: 3}, 
            {lang: "perl", count: 1}, 
            {lang: "php", count: 1}, 
            {lang: "regex", count: 1}
        ]}; 

要定义

report(data)
函数,您只需要
representation
函数和
TrueSets
。候选人以毕业日期代表,而语言则以自我代表。
TrueSet
一致地统计了每个项目的出现频率。只需将您的数据添加到
TrueSets
即可。

function report(data) {

    const
        candidates = TrueSet.of(candidate => candidate.graduate_date, ORDER.ASCENDING, ORDER.INSERTION)
            .letAll(data),
        languages = new TrueSet(language => language)
            .letAll(data
                    .map(candidate => candidate.languages)
                        .flat());
    return {
        candidates:
            candidates 
                .toArray()
                    .map(candidate => ({name: candidate.name, age: candidate.age, phone: candidate.phone})),

            languages:
                languages
                    .toArray()
                            .map(language => ({lang: language, count: languages.n(language)}))
    }
}

您可以通过以下方式验证结果:

const got = report(data);

assert.deepEqual(got, expected);
© www.soinside.com 2019 - 2024. All rights reserved.