最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - Javascript trying to format a string of names - Stack Overflow

programmeradmin0浏览0评论

trying to output:

list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ])
// returns 'Bart, Lisa & Maggie'

list([ {name: 'Bart'}, {name: 'Lisa'} ])
// returns 'Bart & Lisa'

list([ {name: 'Bart'} ])
// returns 'Bart'

list([])
// returns ''

My code:

function list(names){
  let output = "";
  let length = names.length;
  for(i=0; i < length; i++){
    if(length > 2 && i !== length - 1){
     output += names[i]['name'] + ', ' ;
    }
    else if( i == length - 1 && i !== 0) {
      output += ' & ' + names[i]['name'] ;
    } else{
      output += names[i]['name'];
    }
  }
  return output;
}

Expected: 'Bart, Lisa, Maggie, Homer & Marge', instead got: 'Bart, Lisa, Maggie, Homer, & Marge'

Any ideas why the if statement is not working correctly? I cant seem to get it to work.

trying to output:

list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ])
// returns 'Bart, Lisa & Maggie'

list([ {name: 'Bart'}, {name: 'Lisa'} ])
// returns 'Bart & Lisa'

list([ {name: 'Bart'} ])
// returns 'Bart'

list([])
// returns ''

My code:

function list(names){
  let output = "";
  let length = names.length;
  for(i=0; i < length; i++){
    if(length > 2 && i !== length - 1){
     output += names[i]['name'] + ', ' ;
    }
    else if( i == length - 1 && i !== 0) {
      output += ' & ' + names[i]['name'] ;
    } else{
      output += names[i]['name'];
    }
  }
  return output;
}

Expected: 'Bart, Lisa, Maggie, Homer & Marge', instead got: 'Bart, Lisa, Maggie, Homer, & Marge'

Any ideas why the if statement is not working correctly? I cant seem to get it to work.

Share Improve this question edited Feb 19, 2019 at 17:33 m33bo asked Feb 19, 2019 at 17:27 m33bom33bo 1,3541 gold badge18 silver badges39 bronze badges 2
  • your first if condition is giving that ma.. if(length > 2 && i !== length - 1) – ashish singh Commented Feb 19, 2019 at 17:30
  • use reduce to convert array into single value – Mayur Patil Commented Feb 19, 2019 at 17:53
Add a ment  | 

5 Answers 5

Reset to default 4

Here idea is

  1. Get array of name from the input array of objects.
  2. Now get the length of array.
  3. Get the last element of array using pop.
  4. Now check for length if length is 0 return empty string, if 1 than we return just name, if greater than 1 than join input with , and & and last

function list(input){
  input = input.map(({ name }) => name )
  let length = input.length
  let last = input.pop()
  let op = length === 0 ? "" : length === 1 ? last : input.join(',') + ' & ' +last
  console.log(op)
}

list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ])
list([ {name: 'Bart'}, {name: 'Lisa'} ])
list([ {name: 'Bart'} ])
list([])

Array indexes start at 0, so length - 1 is the last element of the array, not the second-to-last.

Try replacing i !== length - 1 with i < length - 2 in your first condition:

function list(names){
  let output = "";
  let length = names.length;
  for(i=0; i < length; i++){
    if(length > 2 && i < length - 2){
     output += names[i]['name'] + ', ' ;
    }
    else if( i == length - 1 && i !== 0) {
      output += ' & ' + names[i]['name'] ;
    } else{
      output += names[i]['name'];
    }
  }
  return output;
}

console.log(list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'}, {name: 'Homer'}, {name: 'Marge'} ]))
// returns Bart, Lisa, Maggie, Homer & Marge

console.log(list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ]))
// returns 'Bart, Lisa & Maggie'

console.log(list([ {name: 'Bart'}, {name: 'Lisa'} ]))
// returns 'Bart & Lisa'

console.log(list([ {name: 'Bart'} ]))
// returns 'Bart'

console.log(list([]))
// returns ''

Cleaning it up a bit using reduceRight and some ES6 features, we could also write this as:

function list(names){
  let length = names.length;
  if (length === 0) {
    return '';
  }

  return names
    .map(n => n.name)
    .reduceRight((acc, cur, i) => `${cur}${i < length - 2 ? ', ' : ' & '}${acc}`);
}

console.log(list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'}, {name: 'Homer'}, {name: 'Marge'} ]))
// returns Bart, Lisa, Maggie, Homer & Marge

console.log(list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ]))
// returns 'Bart, Lisa & Maggie'

console.log(list([ {name: 'Bart'}, {name: 'Lisa'} ]))
// returns 'Bart & Lisa'

console.log(list([ {name: 'Bart'} ]))
// returns 'Bart'

console.log(list([]))
// returns ''

function list(names) {
    const length = names.length;
    return names.reduce((acc, val, idx) => {
        if(idx === 0) {
            return val.name;
        }
        return acc + ((idx === length - 1) ? ' & ' : ', ') + val.name;
    }, '');
}

What your are trying to do is convert a collection into single value. you will face many scenarios for different types of objects. Hence javascript has provided reduce functionality to convert your array collection to a single accumulated value. you don't even need a separate method 'list' to solve this problem. reduce method is neat, self explanatory for new devs and one of the best way to solve such problems.

refer: https://medium.freecodecamp/reduce-f47a7da511a9

The other answer is correct, but just pointing out that there are a few Array prototype methods which can help you without having to manually deal with indexing at all:

function list (names) {
  const first = names.map(it => it.name)
  const last = first.pop()
  return [ first.join(', '), last ].filter(Boolean).join(' & ')
}

If it's not the 1st letter, check if it's the last. If it's the last add ampersand before it, if not add a ma before it:

function list(names) {
  let output = "";
  const length = names.length;
  for (i = 0; i < length; i++) {
    if (i > 0) {
      output += i < length - 1 ? ', ' : ' & ';
    }

    output += names[i].name;
  }
  return output;
}

console.log(list([{ name: 'Bart' }, { name: 'Lisa' }, { name: 'Maggie' }])); // returns 'Bart, Lisa & Maggie'

console.log(list([{ name: 'Bart' }, { name: 'Lisa' }])); // returns 'Bart & Lisa'

console.log(list([{ name: 'Bart' }])); // returns 'Bart'

console.log(list([])); // returns ''

You can also use Array.map() and Array.join() with the same logic:

const addSeparator = (isNotLast) => isNotLast ? ', ' : ' & ';

const list = (names) => 
  names.map(({ name }, i) => i > 0 ? 
    `${addSeparator(i < length - 1)}${name}` : name)
  .join('')


console.log(list([{ name: 'Bart' }, { name: 'Lisa' }, { name: 'Maggie' }])); // returns 'Bart, Lisa & Maggie'

console.log(list([{ name: 'Bart' }, { name: 'Lisa' }])); // returns 'Bart & Lisa'

console.log(list([{ name: 'Bart' }])); // returns 'Bart'

console.log(list([])); // returns ''

发布评论

评论列表(0)

  1. 暂无评论