私が欲しいのはのようなものですがArray.join(separator)
、これは2番目の引数を取るArray.join(separator, beforeLastElement)
ので、私が言う[foo, bar, baz].join(", ", " or")
と"foo, bar or baz"
。最後の要素を分離するために使用される関数を書くことができると思いますArray.slice
が、代わりに使用できるよく知られた方法はありますか?
15 に答える
非常に単純なため、事前定義された関数はありません。
var a = ['a', 'b', 'c'];
var str = a.slice(0, -1).join(',')+' or '+a.slice(-1);
自然言語のフォーマットであるこのような関数の主なユースケースの仕様の問題もあります。たとえば、オックスフォードのコンマロジックを使用すると、探しているものとは異なる結果になります。
// make a list in the Oxford comma style (eg "a, b, c, and d")
// Examples with conjunction "and":
// ["a"] -> "a"
// ["a", "b"] -> "a and b"
// ["a", "b", "c"] -> "a, b, and c"
exports.oxford = function(arr, conjunction, ifempty){
let l = arr.length;
if (!l) return ifempty;
if (l<2) return arr[0];
if (l<3) return arr.join(` ${conjunction} `);
arr = arr.slice();
arr[l-1] = `${conjunction} ${arr[l-1]}`;
return arr.join(", ");
}
したがって、この問題をユーザーランドに任せる方がよいようです。
私が提案してもいいですか:
['tom', 'dick', 'harry'].join(', ').replace(/, ([^,]*)$/, ' and $1')
> "tom, dick and harry"
reduceを使用したインラインソリューション:
[1, 2, 3, 4, 5].reduce((text, value, i, array) => text + (i < array.length - 1 ? ', ' : ' or ') + value);
=> "1, 2, 3, 4 or 5"
いいえ、これは十分に具体的であるため、カスタム関数を作成する必要があります。良いニュースは、あなたが言ったようArray.join
に、すべてのセパレーターの世話をするために使用すると、最後のセパレーターは更新するのに十分簡単になるということです。
@dystroyの答えから構築:
function formatArray(arr){
var outStr = "";
if (arr.length === 1) {
outStr = arr[0];
} else if (arr.length === 2) {
//joins all with "and" but no commas
//example: "bob and sam"
outStr = arr.join(' and ');
} else if (arr.length > 2) {
//joins all with commas, but last one gets ", and" (oxford comma!)
//example: "bob, joe, and sam"
outStr = arr.slice(0, -1).join(', ') + ', and ' + arr.slice(-1);
}
return outStr;
}
使用例:
formatArray([]); //""
formatArray(["a"]); //"a"
formatArray(["a","b"]); //"a and b"
formatArray(["a","b","c"]); //"a, b, and c"
formatArray(["a","b","c","d"]); //"a, b, c, and d"
2021年の回答を更新しました!
「and」や「or」など、最後から2番目の要素と最後の要素の間に異なる区切り文字を設定することが目標の場合は、Intl.ListFormatを使用できます。
それはまさにそれを行い、あなたは無料でi18nを手に入れます。
IE11を除くすべての主要なブラウザでサポートされています。
例:
const vehicles = ['Motorcycle', 'Bus', 'Car'];
const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
console.log(formatter.format(vehicles));
// expected output: "Motorcycle, Bus, and Car"
const formatter2 = new Intl.ListFormat('de', { style: 'short', type: 'disjunction' });
console.log(formatter2.format(vehicles));
// expected output: "Motorcycle, Bus oder Car"
Array.prototype.join2 = function(all, last) {
var arr = this.slice(); //make a copy so we don't mess with the original
var lastItem = arr.splice(-1); //strip out the last element
arr = arr.length ? [arr.join(all)] : []; //make an array with the non-last elements joined with our 'all' string, or make an empty array
arr.push(lastItem); //add last item back so we should have ["some string with first stuff split by 'all'", last item]; or we'll just have [lastItem] if there was only one item, or we'll have [] if there was nothing in the original array
return arr.join(last); //now we join the array with 'last'
}
> [1,2,3,4].join2(', ', ' and ');
>> "1, 2, 3 and 4"
機能バージョン:
/*
* @param {Array.<string>} arr data array
* @param {string} s1 regular separator
* @param {string} s2 last separator
*/
function customJoin(arr, s1, s2) {
return arr.slice(0,-1).join(s1).concat(arr.length > 1 ? s2 : '', arr.slice(-1));
}
function customJoin(arr, s1, s2) {
return arr.slice(0, -1).join(s1).concat(arr.length > 1 ? s2 : '', arr.slice(-1));
}
const arr1 = ['a','b','c','d'];
const arr2 = ['singleToken'];
console.log(customJoin(arr1, ',', ' and ')); // 'a,b,c and d'
console.log(customJoin(arr1, '::', ' and then::')); // 'a::b::c and then::d'
console.log(customJoin(arr2, ',', 'and ')); // 'singleToken'
パッケージjoin-arrayがあります
const join = require('join-array');
const names = ['Rachel','Taylor','Julia','Robert','Jasmine','Lily','Madison'];
const config = {
array: names,
separator: ', ',
last: ' and ',
max: 4,
maxMessage:(missed)=>`(${missed} more...)`
};
const list = join(config); //Rachel, Taylor, Julia, (3 more...) and Madison
遅い答えですが、いくつかのアプローチを追加します。
方法1:Array.splice()を使用して、last delimiter
最後の前の要素を追加し、最後の2つを結合して削除し,
ます。
function join(arr,last)
{
if(!Array.isArray(arr)) throw "Passed value is not of array type.";
last = last || ' and '; //set 'and' as default
(arr.length>1 && arr.splice(-1,0,last));
arr = arr.join().split("");
arr[arr.lastIndexOf(",")]="";
arr[arr.lastIndexOf(",")]="";
return arr.join("");
}
console.log( join([1]) ); //single valued array
console.log( join([1,2]) ); //double valued array
console.log( join([1,2,3]) ); //more than 2 values array,
console.log( join([1,2,3],' or ') ); //with custom last delimiter
console.log( join("name") ); //Non-array type
方法2:Array.reduce()を使用して、各要素をトラバースすることにより文字列を作成します。
function join(arr,last)
{
if(!Array.isArray(arr)) throw "Passed value is not of array type.";
last=last||' and ';
return arr.reduce(function(acc,value,index){
if(arr.length<2) return arr.join();
return acc + (index>=arr.length-2 ? index>arr.length-2 ? value : value+last : value+",");
},"");
}
console.log( join([1]) ); //single valued array
console.log( join([1,2]) ); //double valued array
console.log( join([1,2,3]) ); //more than 2 values array,
console.log( join([1,2,3,4],' or ') ); //with custom last delimiter
console.log( join("name") ); //Non-array type
私にとって最も簡単な解決策は次のとおりです。
['1', '2', '3'].reduce((previous, current, index, array) => {
if (index === array.length - 1) {
return previous + ' & ' + current;
} else {
return previous + ', ' + current;
}
})
function getValuesfromArray(strArray) {
let endString = "";
if (strArray.length > 1) {
const lastEntry = strArray.pop();
endString = strArray.join(", ") + " or " + lastEntry;
}
else {
endString = strArray.toString();
}
return endString;
}
空でないアレイ用のワンライナー
arr.reduce((res, k, i) => [res, k].join(i === arr.length - 1 ? ' or ' : ', '))
破壊を使用した解決策:
const { log } = console;
const formatList = list => {
const [last = "", ...rest] = [...list].reverse();
return rest.length
? [last, rest.reverse().join(", ")].reverse().join(" and ")
: last;
};
log(formatList([1, 2, 3, 4]));
log(formatList(["Me", "Myself", "I"]));
log(formatList(["", ""]));
log(formatList([42]));
log(formatList([]));
DenysSéguretのオックスフォードスタイルの参加ですが、最後のコンマはありません:
function readableJoin(arr, conjunction = 'and', ifEmpty = '') {
const length = arr.length;
switch (length) {
case 0:
return ifEmpty;
case 1:
return arr[0];
case 2:
return arr.join(` ${conjunction} `);
default:
const arrCopy = arr.slice(0, -2);
arrCopy.push(`${arr[length - 2]} ${conjunction} ${arr[length - 1]}`);
return arrCopy.join(', ');
}
}
readableJoin(['one', 'two', 'three']); // 'one, two and three'