【问题标题】:How would I write this reportCandidates' function better?我如何更好地编写这个reportCandidates的功能?
【发布时间】:2018-11-22 05:40:51
【问题描述】:

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

[ 
 {"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


    【解决方案1】:

    一种选择是首先将reduce 放入candidates 子对象中,而push 将每个langauges 放入一个数组中。

    迭代后,对candidates进行排序并从每个候选者中删除graduate_date属性,然后再次使用reducelanguages数组转换为按语言索引的数组,每次递增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);

    【讨论】:

    • 哇,太棒了!我永远不会想象会那样做。非常好...那么我如何按毕业日期以 desc 和语言按字母顺序排列候选人
    • candidates 已经被排序,请参阅sort 函数,要按语言对语言进行排序,请在其lang 属性上使用localeCompare
    • 我可以用它来使名字的第一个字母像小写吗? name = name.charAt(0).toUpperCase() + name.slice(1); a.candidates.push({ 姓名、年龄、电话 });
    • 你想让每个第一个字符大写?是的,该代码看起来可以工作,但请注意,您可以使用括号表示法而不是 charAt 来减少语法噪音,例如 name[0].toUpperCase()
    • 括号符号?这对我来说是新的
    【解决方案2】:

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

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

    【讨论】:

    • 是的,兄弟不错。我改变了一些东西,让所有名字的第一个字母都是大写的,并按字母顺序组织所有语言。谢谢!!!
    【解决方案3】:

    您可以使用Array.reduceObject.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)

    【讨论】:

    • 很有意思你用地图功能来组织候选人哇恭喜...谢谢
    猜你喜欢
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多