2016-07-15 2 views
1

Допустим, у меня есть массив как это:Поиск и фильтрация массива

var arr = ['hello, my', 'hello, my name is', 'hello, my name is newton', 'hello, his', 'hello, his name is', 'hello, his name is pluto', 'hello, she is britney']; 

Я хочу, чтобы фильтровать в:

var arr = ['hello, my name is newton', 'hello, his name is pluto', 'hello, she is britney']; 

Я не знаю, как поставить это, но условие например, если строка элемента массива может быть найдена на другом элементе, ее следует удалить. Как «привет, мой» можно найти точно в следующем следующем элементе «привет», меня зовут «so» hello, мой »должен быть удален.

Фактический массив, который я пытаюсь фильтр:

var arr = ['11 22 13', '11 22 13 34', '11 22 13 34 15', '11 22 13 34 35', '11 22 23', '11 22 23 34', '11 22 23 34 15', '11 22 23 34 35', '31 22 13', '31 22 13 34', '31 22 13 34 15', '31 22 13 34 35', '31 22 23', '31 22 23 34', '31 22 23 34 15', '31 22 23 34 35']; 

Я пытался разбить его на разные группы, но я до сих пор не знаю, что делать с ним. Я покажу это в любом случае:

var threelink = []; 
var fourlink = []; 
var fivelink = []; 

    for(var i=0; i < arr.length; i++){ 
     if(arr[i].length>8&&arr[i].length<12){ 
      fourlink.push(arr[i]); 
     } 
     else if(arr[i].length>11){ 
      fivelink.push(arr[i]); 
     } 
     else { 
      threelink.push(arr[i]); 
     } 
    } 
+0

- тип массива отсортированный? –

+0

да, это сортируется чем-то вроде родителей и детей. как «привет, мой» - это дедушка, «привет», меня зовут «отец» и, наконец, «привет», меня зовут «Ньютон», ребенок –

ответ

1

Plain старый вложенная решение петли, вероятно, быстрее, чем alteratives в этой теме, потому что внутренний контур смотрит на сокращающейся части массива:

function uniqueContents(arr) { 
    var work = arr.slice(), result = [], 
     i, j, l = arr.length, found; 

    work.sort(function (a, b) { 
     return a.length > b.length; 
    }); 

    for (i = 0; i < l; i++) { 
     if (!work[i]) break; 
     found = false; 
     for (j = i + 1; j < l; j++) { 
      if (!work[j]) break; 
      found = work[j].indexOf(work[i]) > -1; 
      if (found) break; 
     } 
     if (!found) result.push(work[i]); 
    } 
    return result; 
} 

Другие, чем это побочные эффекты бесплатно (не искажает вход) и терпимо к null/undefined значениям.

+0

Что вы имеете в виду, не искажает вход? –

+0

Решение James Jithin повторно сортирует входной массив на месте, что может отрицательно повлиять на код, который запускается позже. Функции не должны молча изменять свои аргументы. – Tomalak

3

Я думаю, что вы хотите

arr.filter(function(e, i, a) { 
    return !a.some(function(e2) { 
    return e2 !== e && e2.includes(e); 
    }); 
}) 

Это говорит о том, чтобы фильтровать массив, сохраняя только те элементы, для которых нет НИКАКИХ (!some) других элементов, которые включают его (но не равны ему).

Это немного более компактный с ES6 стрелками функции:

arr.filter((e, i, a) => !a.some(e2 => e2 !== e && e2.includes(e))); 

var arr = ['hello, my', 'hello, my name is', 'hello, my name is newton', 'hello, his', 'hello, his name is', 'hello, his name is pluto', 'hello, she is britney']; 
 

 
var filtered = arr.filter((e, i, a) => !a.some(e2 => e2 !== e && e2.includes(e))); 
 

 
console.log(filtered);

+0

вы протестировали его? это не работает для меня? также я все еще пытаюсь это понять –

0

Если вы просто хотите, чтобы удалить все элементы из array1, которые не появляются в array2, вы можете использовать что-то вроде этого:

var array1 = ['hello, my', 'hello, my name is', 'hello, my name is newton', 'hello, his', 'hello, his name is', 'hello, his name is pluto', 'hello, she is britney']; 
var array2 = ['hello, my name is newton', 'hello, his name is pluto', 'hello, she is britney']; 

for(var i = 0; i < array.lengh; i++){ 
    if(array2.indexOf(array1[i]) == -1){ 
     array1.splice(i, 1); 
    } 
} 

Будем надеяться, что я правильно понял вашу проблему, и это помогает

+0

нет, я боюсь, что это не ответ. Потому что я не знаю, какие элементы будут в array2 –

0

Как насчет этого?

var arr = ['11 22 13', '11 22 13 34', '11 22 13 34 15', '11 22 13 34 35', '11 22 23', '11 22 23 34', '11 22 23 34 15', '11 22 23 34 35', '31 22 13', '31 22 13 34', '31 22 13 34 15', '31 22 13 34 35', '31 22 23', '31 22 23 34', '31 22 23 34 15', '31 22 23 34 35']; 

arr.sort(); 
var filterArray = new Array(); 
for(var i = 0 ; i < arr.length; i++) { 
    if(i + 1 == arr.length) { 
    filterArray.push(arr[i]); 
    } else { 
    if(arr[i+1].startsWith(arr[i])) { 
     continue; 
    } else { 
     filterArray.push(arr[i]); 
    } 
    } 
} 
alert(filterArray); 

JSFiddle

1

Вы можете использовать Array#reduce и Array#filter, для проверки, является ли строка в наборе результатов, чтобы отфильтровать и, если фактическое значение для вставки в наборе результатов.

Это работает для несортированных данных.

var arr = ['hello, my', 'hello, my name is', 'hello, my name is newton', 'hello, his', 'hello, his name is', 'hello, his name is pluto', 'hello, she is britney', 'abc', 'ab'], 
 
    result = arr.reduce(function (r, a, i) { 
 
     var push = true; 
 
     r = r.filter(function (b) { 
 
      push = push && b.indexOf(a) === -1; 
 
      return a.indexOf(b) === -1; 
 
     }); 
 
     push && r.push(a); 
 
     return r; 
 
    }, []); 
 

 
console.log(result);

Смежные вопросы