在数组的开头和结尾处删除null

时间:2019-12-10 00:17:16

标签: javascript algorithm performance

寻找一种算法,该算法将删除在数组的开始 end 处出现的空值,并且中间没有O(n)

例如:

[null, null, 1, 2, 3, null, null, null] -> [1, 2, 3]

[null, null, 1, 2, null, 3, null, null, null] -> [1, 2, null, 3]

[1, null, 2, 3, null, 4, null, null, null] -> [1, null, 2, 3, null, 4]

[null, null, 2, 3, null, 4, null, null, 5] -> [2, 3, null, 4, null, null, 5]

3 个答案:

答案 0 :(得分:3)

有点矮胖但是可以用。

const tests = [[null, null, 1, 2, 3, null, null, null],
[null, null, 1, 2, null, 3, null, null, null],
[1, null, 2, 3, null, 4, null, null, null],
[null, null, 2, 3, null, 4, null, null, 5]];

const strip = (arr) => {
  const end = arr.length-(arr.reverse().findIndex(a => a != null));
  const start = arr.reverse().findIndex(a => a != null);
  return arr.slice(start, end);
};

tests.forEach(a => console.log(strip(a)));

一个循环,检查开始和结束。

const tests = [[null, null, 1, 2, 3, null, null, null],
[null, null, 1, 2, null, 3, null, null, null],
[1, null, 2, 3, null, 4, null, null, null],
[null, null, 2, 3, null, 4, null, null, 5],
[null, null, null, null, null],
[null, 1, null, null, null, null]
];

const strip = (arr) => {
  let start = -1, end = -1, i = 0, x = arr.length - 1;
  while(start === -1 || end === -1) {
    if(start === -1 && arr[i] !== null) {
        start = i;
    }
    if(end === -1 && arr[x] !== null) {      
        end = x+1;
    }
    if(i === x) return [];
    x--;
    i++;
  }
  return arr.slice(start, end);
};




tests.forEach(a => console.log(strip(a)));

好的,这是一个超级简单的解决方案。

const tests = [[null, null, 1, 2, 3, null, null, null],
[null, null, 1, 2, null, 3, null, null, null],
[1, null, 2, 3, null, 4, null, null, null],
[null, null, 2, 3, null, 4, null, null, 5],
[null, null, null, null, null]
];

const strip = (arr) => {
  while(arr[0] === null && arr.length > 0) {
    arr.shift();
  }
  while(arr[arr.length-1] === null && arr.length > 0) {
    arr.pop();
  }
  return arr;
};

tests.forEach(a => console.log(strip(a)));

答案 1 :(得分:1)

这是一个相对较小的解决方案,应为O(n)。您进行一次通过以获取数组的开始和结束位置,然后在进行.slice时进行另一次通过。

const trimmer = arr => {
  const positions = arr.reduce((acc, el, i) => {
    if(el !== null) {
      acc[1] = i + 1;
      if (acc[0] === undefined) acc[0] = i;
    }
    return acc;
  }, [undefined, undefined]);
  return arr.slice(...positions);
}

console.log(trimmer([null, null, 1, 2, 3, null, null, null]));
console.log(trimmer([null, null, 1, 2, null, 3, null, null, null]));
console.log(trimmer([1, null, 2, 3, null, 4, null, null, null]));
console.log(trimmer([null, null, 2, 3, null, 4, null, null, 5]));

答案 2 :(得分:1)

只有两个索引从两端移动,然后调用<vue-pikaday v-model='date' auto-default="autoDefault" :options="pikadayOptions" /> data() { return { autoDefault : true, pikadayOptions: { format : 'YYYY/MM/DD', minDate : moment().toDate(), }, } },

slice