2

I'm trying to implement a slice method for an array, say you have a list of 7 items, but initially it shows 2 items. How would you show more items based on each function click ?

like show 3 more, show 2 more, show 1 more, until there is no more items to show.

https://jsbin.com/ratohehuyi/edit?js,console

I'm stuck on writing the logic, this is just pseudocode

  const arr = ['blueberries', 'oranges', 'grapes', 'bananas', 'kiwis', 'apples', 'coconuts']

  const arrNum = 2

  console.log(arrNum)

  const showMore = (arr) => {
    return arr.slice(0, arrNum * 2 ) // this should increment i think based on each function click 
  }

  console.log(showMore(arr))
8
  • > The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place. Commented May 22, 2020 at 21:28
  • you'll want to use .slice Commented May 22, 2020 at 21:28
  • ok i used it, but still have some issues with the logic. Commented May 22, 2020 at 21:28
  • 1
    use pop or shift. it's easier to reason about. splice should work though Commented May 22, 2020 at 21:29
  • Would you be able to provide an answer, this is a similar implementation to the way facebook/instagram does their comments. Commented May 22, 2020 at 21:31

3 Answers 3

1

How would you show more items based on each function click ?

You have to increment slice of array taken with each click call.

Example

const array = ['blueberries', 'oranges', 'grapes', 'bananas', 'kiwis', 'apples', 'coconuts']

let arrNum = 0;

const listElement = document.querySelector("#list");
const button = document.querySelector("#button");

const showMore = () => {

  arrNum = arrNum + 2;
  const sublist = array.slice(0, arrNum);
  
  let first = listElement.firstElementChild; 
  while (first) { 
    first.remove(); 
    first = listElement.firstElementChild; 
  } 
  
  for(let item of sublist) {
    const itemElement = document.createElement("li");
    itemElement.textContent = item;
    listElement.appendChild(itemElement);
  }
  
  if(sublist.length === array.length) {
    button.style.display = "none";
  }
}

button.addEventListener("click", showMore);

showMore();
<ul id="list">
</ul>
<button id="button">Show more</button>

--Edit

Now when I think of it. This approach is stupid as we are deleting everything with every call.

Here's a bit of improvement.

const array = ['blueberries', 'oranges', 'grapes', 'bananas', 'kiwis', 'apples', 'coconuts']

let from = 0;
let to = 2;

const listElement = document.querySelector("#list");
const button = document.querySelector("#button");

const showMore = () => {

  const sublist = array.slice(from, to);
  from = to;
  to = to + 2;
  
  for(let item of sublist) {
    const itemElement = document.createElement("li");
    itemElement.textContent = item;
    listElement.appendChild(itemElement);
  }
  
  if([...listElement.children].length === array.length) {
    button.style.display = "none";
  }
}

button.addEventListener("click", showMore);

showMore();
<ul id="list">
</ul>
<button id="button">Show more</button>

Sign up to request clarification or add additional context in comments.

4 Comments

appreciate this. This was really meant to be in a react component, just made this as a javascript example so that i get an idea of how to implement it
Updated answer. You have two solutions. Like red pill and blue pill. The latter is red
@JózefPodlecki if I turned that into a one liner, would I trigger deja vu?
@user120242 that would be like going from SSJ2 to SSJ3.
1

Note: Adding for supplementary explanation of OP

The issue is that the increment in the splice method was multiplying by 2

e.g. array.splice(0, arrNum * 2)

This arrNum*2 shifts the position to the right every time arrNum is incremented by a factor of 2.

The effect of using splice in this is similar as to a Queue (fifo) - however, since the values returned on showMore aren't being logged, this is most likely where the confusion lies.

Alternatively, if you wanted to implement a stack (LIFO), you can use the pop method, or replace the position of splice(<index>) to be the offset at the end of the array.

const arr = ['blueberries', 'oranges', 'grapes', 'bananas', 'kiwis', 'apples', 'coconuts']

const showMore = (arr, num) => {
  return arr.splice(0, num) 
}

let firstTwo = showMore(arr, 2) //? [ 'blueberries', 'oranges' ]
console.log(arr)  //? [ 'grapes', 'bananas', 'kiwis', 'apples', 'coconuts' ] 

let nextThree = showMore(arr, 3) //? [ 'grapes', 'bananas', 'kiwis' ]

console.log(arr); //? [ 'apples', 'coconuts' ] 

let last = showMore(arr, 2) //? [ 'apples', 'coconuts' ]
console.log(arr) //? []

Comments

0

You can build a function that takes an increment and an array and return a function that returns bigger slices of the original array after each call.

const slicer =
  (inc, arr, count = 0) =>
    () => arr.slice(0, count+=inc);
    
const show_more = (get_data) => () => {
  console.log(get_data());
};
    
document.querySelector('button')
  .addEventListener('click', show_more(slicer(2, arr)));
<script>
const arr = [ 'blueberries'
            , 'oranges'
            , 'grapes'
            , 'bananas'
            , 'kiwis'
            , 'apples'
            , 'coconuts'
            ];
</script>

<button>show more</button>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.