简体   繁体   English

如有必要,获取带有姓氏缩写的名字列表

[英]Get a list of first names with last name initials if necessary

So in my JS I have an object like so; 所以在我的JS中,我有一个像这样的对象;

[
    {
        firstname: "John",
        lastname: "Smith"
    },
    {
        firstname: "Peter",
        lastname: "Gregory"
    },
    {
        firstname: "John",
        lastname: "Fisher"
    },
    {
        firstname: "Sam",
        lastname: "Fisher"
    }
]

And I'd like to display the first names in a comma-separated string. 我想用逗号分隔的字符串显示名字。 Now this would be simple enough, but I also want to display the first initial of the last name only where necessary, to distinguish two people with the same first name. 现在这已经足够简单了,但是我也想只在必要时显示姓氏的名字的首字母,以区分两个具有相同名字的人。

So, in the end, I'd have this: 因此,最后,我将得到以下信息:

John S., Peter, John F., Sam

Thus far I've been able to do a loop that remembers past initials, but the problem for me becomes the fourth entry in the example; 到目前为止,我已经能够进行一个循环,以记住过去的首字母缩写,但是对我而言,问题就变成了示例中的第四项。 someone with a last name that has had to be distinguished with someone else, but who doesn't a share a first name with anyone. 姓氏必须与其他人区分开来,但不与任何人共享名字的人。

What would be the smartest way of going about this? 解决这个问题的最明智的方法是什么?

Array.map + Array.join will do it. Array.map + Array.join可以做到。 I included a polyfill for Array.map if you need it at the bottom. 如果您需要在底部添加一个Array.map的polyfill。

 var people = [ { firstname: "John", lastname: "Smith" }, { firstname: "Peter", lastname: "Gregory" }, { firstname: "John", lastname: "Fisher" }, { firstname: "Sam", lastname: "Fisher" } ] /* Count number of firstNames */ var firstnames = {}; for (var i = 0; i < people.length; i++) { if (!firstnames[people[i].firstname]) { firstnames[people[i].firstname] = 0; } firstnames[people[i].firstname] ++; } /* Create the string of names */ var peopleString = people.map(function (a) { /* Check if we need a last name here */ var lastname = firstnames[a.firstname] > 1 ? (a.lastname ? ' ' + a.lastname.substr(0, 1) + '.' : '') : ''; return a.firstname + lastname; }).join(', '); document.write(peopleString); /*Polyfill for Array.map taken from MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Polyfill*/ // Production steps of ECMA-262, Edition 5, 15.4.4.19 // Reference: http://es5.github.io/#x15.4.4.19 if (!Array.prototype.map) { Array.prototype.map = function(callback, thisArg) { var T, A, k; if (this == null) { throw new TypeError(' this is null or not defined'); } // 1. Let O be the result of calling ToObject passing the |this| // value as the argument. var O = Object(this); // 2. Let lenValue be the result of calling the Get internal // method of O with the argument "length". // 3. Let len be ToUint32(lenValue). var len = O.length >>> 0; // 4. If IsCallable(callback) is false, throw a TypeError exception. // See: http://es5.github.com/#x9.11 if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. if (arguments.length > 1) { T = thisArg; } // 6. Let A be a new array created as if by the expression new Array(len) // where Array is the standard built-in constructor with that name and // len is the value of len. A = new Array(len); // 7. Let k be 0 k = 0; // 8. Repeat, while k < len while (k < len) { var kValue, mappedValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty internal // method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { // i. Let kValue be the result of calling the Get internal // method of O with argument Pk. kValue = O[k]; // ii. Let mappedValue be the result of calling the Call internal // method of callback with T as the this value and argument // list containing kValue, k, and O. mappedValue = callback.call(T, kValue, k, O); // iii. Call the DefineOwnProperty internal method of A with arguments // Pk, Property Descriptor // { Value: mappedValue, // Writable: true, // Enumerable: true, // Configurable: true }, // and false. // In browsers that support Object.defineProperty, use the following: // Object.defineProperty(A, k, { // value: mappedValue, // writable: true, // enumerable: true, // configurable: true // }); // For best browser support, use the following: A[k] = mappedValue; } // d. Increase k by 1. k++; } // 9. return A return A; }; } 

I guess you could do something like this: 我猜你可以做这样的事情:

var o = {};
var arr = [];
people.forEach(function(val) {
    if (!o.hasOwnProperty(val.firstname)) {
       // didn't see this name before,
       // keeping it so we know we saw it
       // and keeping its index, in case we see the same name again
       var idx = arr.push(val.firstname);
        o[val.firstname] = { idx: idx - 1, val: val };

    }
    else {
        // we saw this name, adding the current with a last name
        // also adding last name to the origninal we saved before
        arr.push(val.firstname + " " + val.lastname.substr(0, 1));
        arr[o[val.firstname].idx] = o[val.firstname].val.firstname + " " + o[val.firstname].val.lastname.substr(0, 1);
    }
})
console.log(arr);

Just if you want an (almost) inline solution... 只是如果您想要一个(几乎)内联解决方案...

var arr = [
    {
        firstname: "John",
        lastname: "Smith"
    },
    {
        firstname: "Peter",
        lastname: "Gregory"
    },
    {
        firstname: "John",
        lastname: "Fisher"
    },
    {
        firstname: "Sam",
        lastname: "Fisher"
    }
];

var out = arr.map (function(i){
    return arr.filter(function(e){
        return e.firstname == i.firstname && true;
    }, []).length > 1 ? (i.firstname + " " + i.lastname.charAt(0)) : (i.firstname);
}, []).toString();

console.log(out);

fiddle http://jsfiddle.net/owqc35p3/2/ 小提琴http://jsfiddle.net/owqc35p3/2/

It will not be that performant compared to many others though, because we're looping arr every time inside the current arr map (also, .toString() can be replaced by .join(" ,"); ) 不过,与其他许多功能相比,性能并不是那么好,因为我们每次都在当前的arr映射内循环arr(同样, .toString()可以由.join(" ,");代替)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从包含名称的字符串中获取缩写和全名 - Get initials and full last name from a string containing names 名字和姓氏缩写的建议 React hooks - suggestion for first and last name initials React hooks 在javascript中使用箭头函数返回名字和姓氏的首字母 - Using arrow function in javascript to return the initials of the First Name and Last Name 获取姓名的首字母,但姓氏除外 - JavaScript - Get initials from name except from last name - JavaScript 在 Javascript 控制台中输出姓氏的第一个字母以及两个大写字母的首字母? - Outputting first letter of last name as well as both initials in Uppercase in Javascript console? 名字的缩写和名字的缩写,保留完整的姓氏 - First and second name initials, preserving full surname 如何获取列表以按姓氏的字母顺序排序,但在javascript中保持名字第一 - How to get list to sort by alphabetically by last name but keep first name first in javascript 如何从对象获取名称的首字母 - How to get the Initials of a Name from an Object 拆分名字和姓氏,如果有多个姓氏相同的人,则将名字的首字母和姓氏重新组合 - Splitting first and last names and then recombining first initial with last name if there are multiple people with the same last name 通过 REGEX 获取带重音字符的全名缩写 - Get Initials of full names with accented characters through REGEX
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM