Поиск объекта в нескольких массивах по значению определенного ключа

#javascript #typescript

#javascript #typescript

Вопрос:

Мне нужно найти объект в нескольких массивах по target значению и вернуть source значение.

Данные выглядят следующим образом:

 {
  "something": [
    {
      "type": "static",
      "source": "data-access-select",
      "target": "data-access-graphql"
    },
    {
      "type": "static",
      "source": "return-me",
      "target": "find-me"
    }
  ],
  "anything": [
    {
      "type": "static",
      "source": "data-access-page-index",
      "target": "data-access-graphql"
    }
  ]
}
  

Итак, существует несколько массивов.

 const depsBuffer = await readFile(
  resolve('node_modules/.cache/nx/nxdeps.json')
)
const deps = JSON.parse(depsBuffer.toString('utf-8')).dependencies

for (const [key, value] of Object.entries(deps)) {
  const res = value.find(x => x.target === 'find-me').source
  console.log(res); // expected: 'return-me'
}
  

Но при этом я получаю ошибку ts Property 'find' does not exist on type 'unknown'

Ответ №1:

Причина ошибки в том, что TypeScript не знает, что value это массив. Он видит value как unknown .

Попробуйте указать тип, чтобы описать ожидаемую форму JSON

 interface Dependencies {
  [key: string]: Array<{
    type: string,
    source: string, 
    target: string
  }>;
}

const depsBuffer = await readFile(
  resolve('node_modules/.cache/nx/nxdeps.json')
);
const deps = JSON.parse(depsBuffer.toString('utf-8')).dependencies as Dependencies;

for (const [key, value] of Object.entries(deps)) {
  const res = value.find(x => x.target === 'find-me').source;
  console.log(res); // expected: 'return-me'
}
  

Ответ №2:

 const deps = {
  "something": [
    {
      "type": "static",
      "source": "data-access-select",
      "target": "data-access-graphql"
    },
    {
      "type": "static",
      "source": "return-me",
      "target": "find-me"
    }
  ],
  "anything": [
    {
      "type": "static",
      "source": "data-access-page-index",
      "target": "data-access-graphql"
    }
  ]
};

const foundElement = Object.values(deps).flat().find(el => el.target === "find-me");
console.log(foundElement.source);  

Комментарии:

1. По-прежнему выдается ошибка ts Property 'flat' does not exist on type 'unknown[]'

2. falt используется для вложенных массивов, чтобы сгладить их exmp: [[a, b,c],[d,e,f]] > [a,b, c, d, e,f] . Я предполагаю, что вы делаете что-то не так, попробуйте утешить ваш инициализированный объект, который вам дает

Ответ №3:

Вы можете попробовать этот код:

 const source = Object.values(deps).reduce((source, array) => {
  const element = array.find(x => x.target === 'find-me');
  if (element) return element.source;
  else return source;
}, null);
  

или это больше похоже на ваш код:

 for (const [_, value] of Object.entries(deps)) {
  const res = value.find(x => x.target === 'find-me');
  // res is going to be undefined if in the array there is not an object with that target
  if (res) console.log(res.source);
}
  

Комментарии:

1. Пока это работает, пожалуйста, предоставьте небольшое объяснение того, что пошло не так в исходном коде и как вы это исправили.

2. обновил ответ чем-то более похожим на ваш код

3. По-прежнему выдается ошибка ts Property 'find' does not exist on type 'unknown'.

Ответ №4:

Используйте Array.prototype.filter() метод. если цель найдена, то первый элемент массива является вашим ответом.

 const array = "Your array here";
let resu<
for (var key in array) {
    result = array[key].filter(r => r.target === "find-me");
    if(result.length > 0){
        break;
    }
}

if(result.length > 0){
    console.log(result[0].source);
}
  

Комментарии:

1. Lioness100 большое вам спасибо за исправление. да, это метод Array.prototype.filter()