Есть ли способ присоединиться к элементам в массиве js, но пусть последний разделитель будет другим?

Я хочу что-то вроде Array.join(separator), но которое принимает второй аргумент Array.join(separator, beforeLastElement), поэтому, когда я говорю [foo, bar, baz].join(", ", " or"), я бы получил "foo, bar or baz". Думаю, я мог бы написать функцию, которая использовала Array.slice для выделения последнего элемента, но есть ли какой-то известный метод, который я мог бы использовать вместо этого?

Ответ 1

Нет, это достаточно специфично, что вам придется писать пользовательскую функцию. Хорошая новость, как вы сказали, когда вы используете Array.join, чтобы позаботиться обо всех разделителях, последнее будет достаточно простым для обновления.

Ответ 2

Там нет предопределенной функции, потому что это довольно просто.

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(", ");
}

Так что, кажется, лучше разрешить эту проблему в пользовательском пространстве.

Ответ 3

Могу ли я предложить:

['tom', 'dick', 'harry'].join(', ').replace(/, ([^,]*)$/, ' and $1')
> "tom, dick and harry"

Ответ 4

Создание ответа @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"

Ответ 5

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"

Ответ 6

есть пакет 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

Ответ 7

компактная версия :)

function customJoin(arr,s1,s2){
return(arr.slice(0,-1).join(s1).concat(arr.length > 1 ? s2 : '', arr.slice(-1)));
}

/* 
arr: data array
s1: regular seperator (string)
s2: last seperator (string)
*/

function customJoin(arr,s1,s2){
return(arr.slice(0,-1).join(s1).concat(arr.length > 1 ? s2 : '', arr.slice(-1)));
}

let arr1 = ['a','b','c','d'];
let arr2 = ['singleToken'];

console.log(customJoin(arr1,',',' and '));
//expected: 'a,b,c and d'
console.log(customJoin(arr1,'::',' and finally::'));
//expected: 'a::b::c and finally::d'
console.log(customJoin(arr2,',','and '));
//expected: 'singleToken'

Ответ 8

Хотя это поздний ответ, добавив некоторые подходы.

Метод 1: Использование Array.splice() добавить last delimiter перед тем последним элементом и присоединиться и удалить два последних ,.

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

Ответ 9

Для меня самое простое решение:

['1', '2', '3'].reduce((previous, current, index, array) => {
    if (index === array.length - 1) {
        return previous + ' & ' + current;
    } else {
        return previous + ', ' + current;
    }
})

Ответ 10

Поточное решение с использованием функции Reduce:

[1, 2, 3, 4, 5].reduce((text, value, i) => !i ? value : '${text}, ${value}', '');

==> "1, 2, 3, 4, 5"