1

I have an array and I want to split it to multiple arrays based on the value 'Finished', when I find it, I split the array.

My code is :

var input = ['urlGettingF', '├─BROKEN─aquaHTTP_404', '├─BROKEN─url1HTTP_404' , 'ok', 'urlok', 'Finished', 
            'urlGettingF2', '├─BROKEN─url1HTTP_404','├─BROKEN─url21HTTP_404', 'Finished',
            'urlGettingF3', '├─BROKEN─url3HTTP_404','├─BROKEN─url213HTTP_404', 'Finished'
];

function chunkArray(array, size) {
  let result = []
  for (value of array) {
    let lastArray = result[result.length - 1]
    if (!lastArray || lastArray.length == size) {
      result.push([value])
    } else {
      lastArray.push(value)
    }
  }
  return result
}

const x = input.findIndex(element => element.indexOf('Finished') > -1)
console.log(chunkArray(input, x + 1));

when I run it I get :

enter image description here

But I want the result will be :

[["urlGettingF", "├─BROKEN─aquaHTTP_404", "├─BROKEN─url1HTTP_404", "ok", "urlok", "Finished"], ["urlGettingF2", "├─BROKEN─url1HTTP_404", "├─BROKEN─url21HTTP_404", "Finished"], ["urlGettingF3", "├─BROKEN─url3HTTP_404", "├─BROKEN─url213HTTP_404", "Finished"]]

When I find Finished, I split my array based on her index, you can see my code in jsbin https://jsbin.com/benozuyutu/1/edit?js,console

How I can fix it ?

5 Answers 5

2

You might find all occurrences of Finished with .reduce, then create a new array by .sliceing each occurrence at the found indicies:

var input = ['urlGettingF', '├─BROKEN─aquaHTTP_404', '├─BROKEN─url1HTTP_404', 'ok', 'urlok', 'Finished',
  'urlGettingF2', '├─BROKEN─url1HTTP_404', '├─BROKEN─url21HTTP_404', 'Finished',
  'urlGettingF3', '├─BROKEN─url3HTTP_404', '├─BROKEN─url213HTTP_404', 'Finished'
];

const finishedIndicies = input.reduce((a, item, i) => {
  if (item === 'Finished') {
    a.push(i);
  }
  return a;
}, []);
const chunked = finishedIndicies.map(
  (sliceIndex, i, arr) => input.slice(arr[i - 1] === undefined ? 0 : arr[i - 1] + 1, sliceIndex + 1)
);
console.log(chunked);

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

3 Comments

.reduce can be replaced with a simple for loop. .reduce reduces the code readability.
@AdityaBhave Opinion-based, but I prefer reduce because it is an appropriate tool for transforming an array into a single accumulator, when that accumulator isn't one-to-one- with the input array
@CertainPerformance yes.. I agree that it is opinion based. Check this youtube video from Surma and Jake youtube.com/watch?v=qaGjS7-qWzg
2

var input = ['urlGettingF', '├─BROKEN─aquaHTTP_404', '├─BROKEN─url1HTTP_404', 'ok', 'urlok', 'Finished', 'urlGettingF2', '├─BROKEN─url1HTTP_404', '├─BROKEN─url21HTTP_404', 'Finished', 'urlGettingF3', '├─BROKEN─url3HTTP_404', '├─BROKEN─url213HTTP_404', 'Finished']

const res = input
  .join(' ')
  .split('Finished')
  .map(item => item.split(' ').filter(item => item))
  .filter(item => item.length)
  .map(item => [...item, 'Finished'])
 
console.log(res)

Comments

1

var input = ['urlGettingF', '├─BROKEN─aquaHTTP_404', '├─BROKEN─url1HTTP_404', 'ok', 'urlok', 'Finished',
  'urlGettingF2', '├─BROKEN─url1HTTP_404', '├─BROKEN─url21HTTP_404', 'Finished',
  'urlGettingF3', '├─BROKEN─url3HTTP_404', '├─BROKEN─url213HTTP_404', 'Finished'
];

function chunkArray(arr) {
  let result = [
    []
  ];
  let index = 0;
  arr.forEach((x, i) => {
    result[index].push(x);
    if ((i + 1) < arr.length && x.includes('Finished')) {
      index++;
      result[index] = [];
    }
  });
  return result
}
console.log(chunkArray(input));

Comments

1

You can use following algorithm.

  1. Find indexOf('Finished')
  2. Use Array.splice function to get the values till the index. .splice also updates the existing Array.
  3. Do above until indexOf('Finished') > -1
  4. Finally, add the remaining input array in the output array

let input = ['urlGettingF', '├─BROKEN─aquaHTTP_404', '├─BROKEN─url1HTTP_404', 'ok', 'urlok', 'Finished',
  'urlGettingF2', '├─BROKEN─url1HTTP_404', '├─BROKEN─url21HTTP_404', 'Finished',
  'urlGettingF3', '├─BROKEN─url3HTTP_404', '├─BROKEN─url213HTTP_404', 'Finished'
];

let output = [];

while (true) {
  output.push(input.splice(0, input.indexOf('Finished') + 1));

  if (input.indexOf('Finished') === -1) {
    input.length && output.push(input); //to add all remaining values
    
    break;
  }
}

console.log(output);

Comments

1

You can use reduce method. In reduce method, it is necessary to check whether keyword to find exists and if exists push into newly created array. Otherwise, we are pushing into existing array:

let keywordToFind = 'urlGettingF';

const result = input.reduce((a, c) => {
    (c.includes(keywordToFind)) ? a.push([c]) : a[a.length - 1].push(c); 
    return a;
}, []);

An example:

var input = ['urlGettingF', '├─BROKEN─aquaHTTP_404', 
   '├─BROKEN─url1HTTP_404', 'ok', 'urlok', 'Finished',
  'urlGettingF2', '├─BROKEN─url1HTTP_404', '├─BROKEN─url21HTTP_404', 'Finished',
  'urlGettingF3', '├─BROKEN─url3HTTP_404', '├─BROKEN─url213HTTP_404', 'Finished'
];


let keywordToFind = 'urlGettingF';
const result = input.reduce((a, c) => {
    (c.includes(keywordToFind)) ? a.push([c]) : a[a.length - 1].push(c);
    return a;
}, []);

console.log(result);

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.